Redshift UPDATE使用Seq Scan非常慢

时间:2017-02-21 09:40:32

标签: sql amazon-redshift

我必须在一个大表(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))

我不知道我还能在问题中添加什么来使其更清晰,我很乐意听到任何建议。

2 个答案:

答案 0 :(得分:1)

您是否尝试删除交错排序键并将其替换为uid上的简单排序键或带有uid作为第一列的复合排序键?

此外,名称uid让我觉得您可能正在使用GUID / UUID作为值。我建议这是Redshift中id值的反模式,尤其是排序键。

GUID / UUID id的问题:

  • 不要以可预测的顺序发生
    • 经常触发完整的顺序扫描
    • 新行总是会破坏排序
  • 压缩很差
    • 需要更多磁盘空间进行存储
    • 查询时需要读取更多数据

答案 1 :(得分:0)

redshift中的更新是删除然后插入。设计的Redshift只是将行标记为已删除,而不是物理删除(鬼行)。显式 vacuum delete only<回收空间所需的table_name>

SEQ。扫描受这些鬼行的影响。建议运行上面的命令并稍后检查查询的性能。