我在 Redshift 集群中有一个包含 50 亿行的表。我有一项工作尝试根据某些过滤器更新某些列值。更新此表中的任何内容都非常慢。这是一个例子:
Update tbl1
set price=tbl2.price, flag=true
from tbl2 join tbl1 on tbl1.id=tbl2.id
where tbl1.time between (some value) and
tbl2.createtime between (some value)
我在 time 上有排序键,在 id 上有 dist 键。当我检查 stl_scan 表时,它显示我的查询正在每个切片上扫描 5000 万行,并且每个切片上仅返回 50K 行。 20 分钟后我停止了查询。
为了进行测试,我创建了包含 10 亿行的相同表,并且相同的更新查询花费了 3 分钟。
当我以相同的条件运行 select 时,我会在几秒钟内得到结果。我做错了什么吗?
我相信正确的语法是:
Update tbl1
set price = tbl2.price,
flag = true
from tbl2
where tbl1.id = tbl2.id and
tbl1.time between (some value) and
tbl2.createtime between (some value);
请注意,
tbl1
仅在update
子句中提及一次。 没有连接,只有关联子句。
提示就在那里。 50m 找到 50k,它的慢意味着该切片未按 id 排序。
dist 键必须包含在排序键中。 既然你加入了...
距离 = id 排序 = id, 时间
您的测试成功了,因为默认情况下插入是按 id 添加并按时间排序的,但实际上,随着更新,除非您定期执行表清理,否则一段时间后它会变得混乱。 不要忘记排序和分布的列必须是原始的(未压缩的)