我正面临着一项任务,即不可能从Amazone Redshift提取大量数据到另一个表。肯定需要更有效的方法,但是我是SQL和AWS的新手,所以决定向这个聪明的社区寻求建议。
这是我最初的SQL查询,需要花费很长时间:
-- STEP 1: CREATE A SAMPLE FOR ONE MONTH
SELECT DISTINCT at_id, utc_time, name
INTO my_new_table
FROM s3_db.table_x
WHERE type = 'create'
AND (dt BETWEEN '20181001' AND '20181031');
什么是最好的方法?我当时正在考虑使用python和sqlalchemy创建具有1m行大块的数据帧,然后将其插入到新表中(我需要事先创建)。这行得通吗?:
from sqlalchemy import create_engine
import os
import pandas as pd
redshift_user = os.environ['REDSHIFT_USER']
redshift_password = os.environ['REDSHIFT_PASSWORD']
engine_string = "postgresql+psycopg2://%s:%s@%s:%d/%s" \
% (redshift_user, redshift_password, 'localhost', XXXX, 'redshiftdb')
engine = create_engine(engine_string)
for df in pd.read_sql_query("""
SELECT DISTINCT at_id, utc_time, name
INSERT INTO my_new_table
FROM s3_db.table_x
WHERE type = 'create'
AND (dt BETWEEN '20181001' AND '20181031');
""", engine, chunksize=1000000):
答案 0 :(得分:2)
您应该使用CREATE TABLE AS。
这允许您指定SELECT
语句并将结果直接存储到新表中。
与下载数据并重新上传相比,效率大大提高。
您也可以CREATE TABLE LIKE
,然后将其装入数据。参见:Performing a Deep Copy
您还可以UNLOAD
数据到Amazon S3,然后通过COPY
再次加载,但是使用CREATE TABLE AS
绝对是最佳选择。
答案 1 :(得分:1)
请参考AWS指南中的RedShift和Spectrum最佳实践;我把链接放在这篇文章的结尾。根据您的问题,我假设您要从基于RedShift Spectrum的表“ s3_db.table_x”中提取,转换并加载大量数据,并将其加载到新的RedShift表“ my_new_table”中
以下是基于AWS建议的一些建议:
使用适当的分发键,排序键和压缩编码创建RedShift表。在较高级别上,“ at_id”似乎最适合作为您的需求的分区键,而“ utc_time”作为您的需求的排序键,但是请确保参考RedShift表设计3的AWS准则。
如前所述,您的数据量很大,您可能希望根据“ type”和“ dt”列对S3源表“ s3_db.table_x”进行分区(如频谱中第4点的建议)最佳做法1)。
在Spectrum的选择查询中将DISTINCT
替换为GROUP BY
(Spectrum Best Practices 1中的第9点)。
AWS建议(Spectrum最佳实践1中的第7点)使用CREATE TABLE AS SELECT
或SELECT INTO
语句简化ETL流程,其中您可以将转换逻辑放在选择组件以将数据直接从S3加载到RedShift。
redshift spectrum best practices
redshift table design playbook
答案 2 :(得分:0)
现在看来,您的源数据存储在Amazon S3中,并且您一直在使用Redshift Spectrum表(指向S3中的数据)作为源。
首选方法是:
COPY
命令将数据加载到Redshift表中CREATE TABLE AS
命令将新Redshift表中的数据提取(ETL)到所需的表中。如果您定期执行此操作,将来可以使用TRUNCATE
和INSERT INTO
重新加载表。