【问题标题】:Slow Query Performance on Large Table大表查询性能慢
【发布时间】:2021-09-26 10:08:30
【问题描述】:

我有一个包含 5600 万行的表。

此表在从 KAFKA 加载流数据时每 5 分钟处理一次高负载的 UPSERTS。每次加载大约 200-500k 更新。

当我对其中一个时间戳列运行带有 ORDER BY 的 SELECT 时,需要 5-7 分钟才能返回结果。

我为该列尝试了 Cluster Key,但由于该表上的 DML 操作很高,并且列本身的基数很高,因此集群效率低且成本高。

到目前为止,唯一将查询时间显着减少到大约 15 秒的想法是将仓库大小从小增加到 X-Large。

我不相信唯一的解决方案是增加仓库规模。这里的任何建议都会很棒!

【问题讨论】:

  • ORDER BY 操作通常需要更大的仓库,因此它们有足够的空间进行分类。如果您没有按时间戳字段进行过滤,那么聚类不会帮助您进行排序操作。查看 SQL 配置文件以了解初始扫描是否花费您时间与排序。如果是这种情况,您是否看到大量溢出到远程存储?如果是这样,您需要一个更大的仓库。
  • 您是否尝试“选择顺序”这 5600 万行?您对查询有限制吗?
  • 我正在无限制地查询select * from table order by date desc ,但是,我认为 DataGrip 自动将查询限制为 500。我检查了查询计划,排序是最昂贵的操作,有很多溢出到远程贮存。表中还有 40 列。显着减少查询执行时间的因素是限制结果、选择中的列和更大的仓库。谢谢!

标签: query-optimization snowflake-cloud-data-platform clustering-key


【解决方案1】:

date(timestamp)(或基数较低的东西)上进行聚类会更有效,尽管由于更新量很大,它仍然会很昂贵。

在欢乐时光活动中,我听说一位 Snowflake 用户通过对迟到的事实(例如 iff(event_date<current_date, true, false)))进行聚类,在类似(ish)场景中取得了可接受的结果(尽管我认为他们是 INSERTing 而不是 @987654324 @ing,在后一种情况下,无论如何都必须重新编写微分区,所以它可能没有多大帮助。)

还有其他事情需要考虑。

检查查询计划以确认排序是问题所在(例如,在排序上花费了大量时间。)在没有看到您的实际查询的情况下,我想知道是否大部分时间都花在了表扫描上(当它是从远程存储中获取数据。)如果更大的仓库可以提高性能,则很可能是这种情况,因为集群中每个添加的节点都意味着可以同时读取更多的微分区。

【讨论】:

  • 我尝试了上述方法,但由于 UPSERT 的数量过多,集群无效。好像限制了查询结果和列在小仓库上的select语句返回结果大约4秒!考虑到这一点,如果我需要更快的结果,我可以增加仓库规模,但这已经是最佳选择了!
【解决方案2】:

你在反对:

  1. 真正的时间戳列?
  2. JSON 列转换为时间戳但没有 附加功能?
  3. JSON 中有多少个字段
  4. UPDATE 与 INSERT 的相对比率是多少?
  5. 您查看过集群统计信息吗?

【讨论】:

  • 1.是 2. 否 3. N/A 4. 更新比插入多,但不确定确切的比例。我会说至少 75% 是更新。其余为插入。 5. 是的,每次 upsert 后的 avg cluster depth 相当高,在 200-400 之间,并且微分区大多位于直方图的下端。如上所述,我发现限制查询结果集和 select 中的列将执行时间大大减少到 4 秒左右。
  • 仅供参考,限制结果集通常是处理完所有行后的最后一步。它只会减少传输时间。很高兴你解决了。
猜你喜欢
  • 1970-01-01
  • 2014-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-11
  • 2018-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多