同时在 AWS Redshift 中“CREATE TABLE LIKE”并更改一些列的默认值 删除这些列并再次添加使用适当的列以编程方式生成临时表创建脚本并去掉CREATE TABLE LIKE填写原始 CSV 文件中的 partition_* 字段

问题描述

工作流程

  1. 在数据导入工作流中,我们使用 CREATE TABLE LIKE statement 创建临时表。
CREATE TABLE abc_staging (LIKE abc INCLUDING DEFAULTS);
  1. 然后,我们运行 COPY 将 CSV 数据从 S3 导入临时表。

  2. CSV 中的数据不完整。即,CSV 文件中缺少字段 partition_0partition_1partition_2;我们像这样填写它们:

UPDATE
  abc_staging
SET
  partition_0 = 'BUZINGA',partition_1 = '2018',partition_2 = '07';

问题

这个查询看起来很昂贵(通常需要大约 20 分钟),我想避免它。如果我可以在创建 DEFAULT 表时在这些列上配置 abc_staging 值,那么这可能是可能的。我没有找到任何关于如何做到这一点的方法;也没有任何不可能的明确指示。所以也许这仍然是可能的,但我想知道如何做到这一点?

我考虑过的替代解决方

删除这些列并再次添加

这很容易做到,但 ALTER TABLE ADD COLUMN 只会将列添加到列列表的末尾。在 abc 表中,它们不在列列表的末尾,这意味着 abcabc_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 分钟(包括 COPYDELETE 重复项和 ALTER TABLE APPEND)。

磁盘空间不再攀升至 100%。

感谢大家的帮助!