使用大表连接更新 Amazon Redshift 中的列

Posted

技术标签:

【中文标题】使用大表连接更新 Amazon Redshift 中的列【英文标题】:Update column in Amazon Redshift with join for big tables 【发布时间】:2020-02-10 13:43:49 【问题描述】:

我有 500M 行和 30 列的表(带有 bigint ID 列),我们称之为big_one。 此外,我还有另一个表extra_one,具有相同的行数和相同的 ID 列,但有两个新列包含我想包含在第一个表中的额外数据。 我在第一个表中添加了两个额外的列,并希望根据连接更新数据。

查询很简单:

update big_one set
    col1=extra_one.col1,
    col2=extra_one.col2
from extra_one
where big_one.id=extra_one.id;

但在执行过程中,磁盘空间使用率急剧增加至 100%。在开始之前,我在 4 个节点上有 23.41% 的可用空间(每个节点 160GB,总共 640GB)。 big_one 表最初使用了大约 18% 的空间。这 23.41% 表明我有大约 490GB 的可用磁盘空间来顺利执行更新。但 Redhisft 的想法不同。

两个新列是 md5 哈希(因此它们的长度为 32 个字符)(理想情况下它应该占用 16GB 的空间)。

回顾:

    我有一张宽桌big_one

    有另一个表 extra_one(总共 3 列),具有相同的 ID 和记录数。

    我向big_one 添加了两个新列。

    我想用来自extra_one 的数据丰富big_one。 (进入那 2 个新列)

Q1:关于如何执行如此大的更新有什么建议吗?

Q2:如果我将创建将连接两个表的 VIEW 然后使用它,它会不会让我摆脱这种空间耗尽的情况?在这种情况下,Redshift 如何与 VIEW(未具体化)一起使用。

【问题讨论】:

aviary_ids 是什么/在哪里? big_one 和 extra_one 有多大(行和字节)? id是唯一的吗?什么是排序/分布键?在运行此之前,您是否已清理并分析了两个表? @JonScott 已修复。应该是 extra_one。 @JonScott 两者都有 bigint 类型的 id 列。是的,该列是唯一的(两个表都相同。)在运行它之前已经完成了真空。没有运行“分析”。没有 sortkey/distkey 的表,都是从“create table TABLENAME as select ...”创建的 我认为当您更新每一行时,它会将其移到表格的末尾。从而产生你的问题。您可以拆分更新(10 x 1/10 吗?)或者您可以创建/添加更多空间吗? @JonScott,是的,通过将集群更新为 8 个节点 (1280GB),执行它需要占用所有容量的 75%。但为什么?这是一个巨大的开销。我该如何改进呢? 【参考方案1】:

不要在大量行上使用UPDATE

在 Amazon Redshift 中修改行时,现有行被标记为已删除,并且新行被追加到表中。这将有效地使表的大小加倍并浪费大量磁盘空间,直到表被清理。它也很慢!

改为:

创建一个联接两个表的查询 使用查询填充新表(见下文) 删除旧表并重命名新表,以便它替换原始表(或截断原始表并将数据复制回其中)

您可以使用CREATE TABLE LIKE 基于现有表创建一个新的空表。

来自CREATE TABLE - Amazon Redshift:

LIKE parent_table [ INCLUDING | EXCLUDING DEFAULTS ] 一个指定现有表的子句,新表会自动从该表中复制列名、数据类型和 NOT NULL 约束。新表和父表是解耦的,对父表所做的任何更改都不会应用于新表。仅当指定了 INCLUDING DEFAULTS 时,才会复制复制的列定义的默认表达式。默认行为是排除默认表达式,以便新表的所有列都具有空默认值。

使用 LIKE 选项创建的表不继承主键和外键约束。 LIKE 表继承了分布样式、排序键、BACKUP 和 NULL 属性,但您不能在 CREATE TABLE ... LIKE 语句中显式设置它们。

【讨论】:

以上是关于使用大表连接更新 Amazon Redshift 中的列的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Amazon Redshift UNLOAD 性能对于新数据要好得多?

如何使用 Amazon Redshift 中的临时表列更新现有表中的列?

如何更新 Amazon Redshift 上的 Python 库?

从 tableau 服务器连接 amazon redshift 服务器

到 Amazon Redshift 的 ODBC 连接字符串

我们可以通过没有密码的linux shell脚本连接amazon redshift吗?