我必须在一个大表(600米行)中更新大约300行,并且我试图让它更快。
我使用的查询有点棘手:
UPDATE my_table
SET name = CASE WHEN (event_name in ('event_1', 'event_2', 'event_3'))
THEN 'deleted' ELSE name END
WHERE uid IN ('id_1', 'id_2')
我尝试在此查询中使用EXPLAIN,我得到:
XN Seq Scan on my_table (cost=0.00..103935.76 rows=4326 width=9838)
Filter: (((uid)::text = 'id_1'::text) OR ((uid)::text = 'id_2'::text))
我有一个交叉排序键,uid是此sortkey中包含的列之一。 查询看起来像这样的原因是在实际上下文中SET中的列数(以及名称)可能会有所不同,但它可能不会超过10。 基本的想法是我不想要交叉连接(更新规则是特定于列,我不想将它们混合在一起)。 例如,将来会出现如下查询:
UPDATE my_table
SET name = CASE WHEN (event_name in ("event_1", "event_2", "event_3")) THEN 'deleted' ELSE name END,
address = CASE WHEN (event_name in ("event_1", "event_4")) THEN 'deleted' ELSE address END
WHERE uid IN ("id_1", "id_2")
无论如何,回到第一个查询,它会运行很长时间(大约45分钟)并占用100%的CPU。
我试着检查更简单的查询:
explain UPDATE my_table SET name = 'deleted' WHERE uid IN ('id_1', 'id_2')
XN Seq Scan on my_table (cost=0.00..103816.80 rows=4326 width=9821)
Filter: (((uid)::text = 'id_1'::text) OR ((uid)::text = 'id_2'::text))
我不知道我还能在问题中添加什么来使其更清晰,我很乐意听到任何建议。
答案 0 :(得分:1)
您是否尝试删除交错排序键并将其替换为uid
上的简单排序键或带有uid
作为第一列的复合排序键?
此外,名称uid
让我觉得您可能正在使用GUID / UUID作为值。我建议这是Redshift中id
值的反模式,尤其是排序键。
GUID / UUID id
的问题:
答案 1 :(得分:0)
redshift中的更新是删除然后插入。设计的Redshift只是将行标记为已删除,而不是物理删除(鬼行)。显式 vacuum delete only<回收空间所需的table_name> 。
SEQ。扫描受这些鬼行的影响。建议运行上面的命令并稍后检查查询的性能。