问题描述
工作流程
- 在数据导入工作流中,我们使用
CREATE TABLE LIKE
statement 创建临时表。
CREATE TABLE abc_staging (LIKE abc INCLUDING DEFAULTS);
-
然后,我们运行
COPY
将 CSV 数据从 S3 导入临时表。 -
CSV 中的数据不完整。即,CSV 文件中缺少字段
partition_0
、partition_1
、partition_2
;我们像这样填写它们:
UPDATE
abc_staging
SET
partition_0 = 'BUZINGA',partition_1 = '2018',partition_2 = '07';
问题
这个查询看起来很昂贵(通常需要大约 20 分钟),我想避免它。如果我可以在创建 DEFAULT
表时在这些列上配置 abc_staging
值,那么这可能是可能的。我没有找到任何关于如何做到这一点的方法;也没有任何不可能的明确指示。所以也许这仍然是可能的,但我想知道如何做到这一点?
我考虑过的替代解决方案
删除这些列并再次添加
这很容易做到,但 ALTER TABLE ADD COLUMN
只会将列添加到列列表的末尾。在 abc
表中,它们不在列列表的末尾,这意味着 abc
和 abc_staging
的架构将不匹配。这会破坏我用来将数据从临时表移动到主表的 ALTER TABLE APPEND
操作。
注意。重新排序 abc
表中的列以缓解这个困难will require recreating 我想避免的巨大 abc
表。
使用适当的列以编程方式生成临时表创建脚本并去掉CREATE TABLE LIKE
如果我找不到更好的解决方案,我将不得不这样做。
填写原始 CSV 文件中的 partition_*
字段
这是可能的,但会破坏向后兼容性(我可能已经有数十万个文件)。更难但可控。
解决方法
正如您发现的那样,您创建的表与原始表不完全相同,而且 Redshift 不允许您更改列的默认值。您建议的路径可能是最好的(明确定义临时表)。
由于我不知道您的确切情况,其他路径可能会更好,所以我会稍微探索一下。首先,当您更新临时表时,您实际上是在读取表中的每一行,使该行无效,并在表的末尾写入一个新行(带有新信息)。这会导致大量无效的行。现在,当您执行 ALTER TABLE APPEND 时,所有这些无效的行都将添加到您的主表中。除非您事先将临时台吸尘。因此,您可能无法从 ALTER TABLE APPEND 中获得您想要的值。
最好使用 ORDER BY 子句将数据插入到主表中。这比 ALTER TABLE APPEND 语句慢,但您不必执行 UPDATE,因此整个过程可能会更快。由于减少了对 VACUUM 的需求,您可以走得更远。您的情况将决定这是否更好。只是您列表中的另一个选项。
我很好奇你的更新速度。这只需要读取然后写入临时表中的每一行。除非临时表非常大,否则这似乎不需要 20 分钟。其他活动可能会造成这种放缓。只是好奇。
另一种选择是将主表更改为最后包含这 3 列(是的,这需要一些工作)。通过这种方式,您可以将列添加到暂存表,并且事情将排列为 ALTER TABLE APPEND。只是另一种可能性。
,最简单的解决方案是将必要的 partition_*
字段添加到源 CSV 文件中。
采用该更改并从导入器管道中移除 UPDATE
后,性能得到了极大提升。现在每次导入总共需要大约 10 分钟(包括 COPY
、DELETE
重复项和 ALTER TABLE APPEND
)。
磁盘空间不再攀升至 100%。
感谢大家的帮助!