2017-02-21 118 views
0

我必须更新大表(600米行)中的约300行,我试图使其更快。Redshift更新使用序列扫描非常缓慢

我使用的查询是有点棘手:

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

由于CASE语句中的WHERE关键字会导致错误,所以您的实际查询必须相当不同。那里有一个子选择吗?另外,桌子上有什么? – systemjack

+0

啊,确实现在纠正了它。 –

+0

您的查询对我而言看起来不错。我自己并没有很好的交错排序键。在不属于排序关键字的列上进行过滤使用复合排序关键字与交错关键字,我仍然获得了10倍左右的改进。在sortkey列上过滤应该会更好。我们放弃了使用交错密钥,直到Redshift将它们整理出来。 – systemjack

回答

1

您是否尝试删除交叉排序键,并使用uid上的简单排序键或uid作为第一列来替换它?

此外,名称uid使我认为您可能正在使用GUID/UUID作为值。我建议这是一个反模式对于Redshift中的id值,特别是对于排序键。

问题与GUID/UUID id

  • 不会出现在可预见的序列
    • 往往会引发一个完整的顺序扫描
    • 新行总是打乱排序
  • 压缩很差
    • 需要用于存储更多的磁盘空间
    • 需要更多数据要读取查询在红移
+0

是的,uid是MongoId字符串。只是意识到sortkey至少很可能不起作用,因为在600mil行中只有几百万行被排序。这可能需要提出另一个问题,但是也许你可以提出一些建议:如果一张表太大以致吸尘时间过长,并且深层复制需要更多的磁盘空间而不是可用,那么可以通过另一种方法重新索引表格? –

+1

这取决于表格有多大TBH。有了一个真正巨大的桌子,你可以把它分成包含一个有限的数据集(例如一个星期或一个月)和一个'UNION ALL'的更小的表格,以替换原始表格。你没有提到你的'DISTSTYLE' - 我会尝试使用'uid'作为时间戳列上排序键的分配键。 –

+0

如果您没有空间,可以对S3执行增量式卸载,请删除您卸载的范围,然后从S3复制到新表格。另外,如果您有空间问题并且尚未启用压缩,那么这将是一个很好的机会:http://docs.aws.amazon.com/redshift/latest/dg/t_Compressing_data_on_disk.html。 – systemjack

0

更新删除,然后插入时。按设计红移只需将行标记为已删除,而不是物理删除它们(幻影行)。明确真空只删除< table_name>需要回收空间。

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