amazon-web-services - 如何阅读红移查询计划?
问题描述
我有这个查询需要几个小时才能完成。如何优化查询?
# explain select setup from user_logs_dlr_sept_oct2020 as a inner join beba_eme_receiver_dlr_2014_198_eme_sept2020 as b on a.messageid=b.batched
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
XN Hash Join DS_BCAST_INNER (cost=1940783.40..62105890177235.56 rows=195463968 width=393)
Hash Cond: (("outer".messageid)::text = ("inner".batched)::text)
-> XN Seq Scan on user_logs_dlr_sept_oct2020 a (cost=0.00..5198612.48 rows=519861248 width=423)
-> XN Hash (cost=1552626.72..1552626.72 rows=155262672 width=30)
-> XN Seq Scan on beba_eme_receiver_dlr_2014_198_eme_sept2020 b (cost=0.00..1552626.72 rows=155262672 width=30)
(5 rows)
“show create table user_logs”是我在 MySQL 中使用的命令。如何检查表是否包含 redshift 中的 distkey 或 sortkey?
解决方案
我喜欢从下往上阅读这些内容。这是我看到的:
- beba_eme_receiver_dlr_2014_198_sept2020 的扫描:从磁盘读取表。155M 行和 30 列。Redshift 认为这不会花费太长时间。
- 对此表数据执行哈希以准备加入
- 扫描 user_logs_dlr_sept_oct2020:从磁盘读取表。519M 行和 423 列。Redshift 预测这比另一个表需要更长的时间,但非常长。
- 这些表的哈希连接条件为 - (("outer".messageid)::text = ("inner".batched)::text)。这就是事情的发展方向。看到这一步的成本价值了吗?它增长到 62105890177235.56,这是一个很大的数字。
基于这个计划,我很惊讶查询只需要几个小时而不是几天,但这指出了一个重要的点——这只是对预执行计划的分析。这不是实际发生的事情。在控制台上,您可以查看查询的“实际执行”统计信息,以了解每个步骤需要多长时间,但我希望它会显示问题出在哈希连接步骤中。
那么发生了什么以及如何改进呢?首先,您需要记住 Redshift 是建立在计算节点集群上的,并且它们之间存在网络连接。哪些数据在哪个节点上由表的分布键确定(我希望您没有将它们设置为偶数分布)。因此,当需要执行连接时,需要将与连接条件匹配的数据“移动”到同一节点以执行连接。在您的计划中,您会看到“Hash Join DS_BCAST_INNER”,这意味着来自您的一个表的所有数据都正在网络广播到所有其他节点 - 不好。理想情况下,您的表已经分布了表数据,因此不需要移动。您可能正确设置了此设置,但还有另一个问题正在阻止。
阻塞问题是您将值转换为两个连接字段的文本。您通常会看到 Redshift 会定义一个计划,该计划将设置哪个节点负责连接条件和数据的哪些值将“分发”(而不是广播)到负责的节点。但是由于您在条件下对连接的两侧进行了强制转换,因此规划器不知道如何设置它,并且需要将所有表数据广播到所有节点 - 网络开销很大的操作。
我将努力改进此查询:
- 在条件下(至少一侧和较大的桌子一侧,如果可能)从连接中移除演员表。这可能需要查看您的表模式。
- 重新评估这些表的分布,看看它们是否可以分布在相似的键上(或者对较小的表使用 DISTSTYLE ALL)
- 重新评估让这么多行和列流入联接的需要。将 where 子句添加到表扫描可以大大减少基于网络的连接的时间和费用。
当您尝试改进时,我会查看实际执行统计信息,因为这可能与查询计划器的成本预期不同。
推荐阅读
- post-processing - 当我从下拉列表中打开后期处理时,我的场景变为空白和灰色
- xml - 肥皂信封格式无效
- python - vtkBoxWidget 不适用于 PyQt5 应用程序
- powershell - 文件夹和子文件夹中的列表文件详细信息重复
- python - django 租户:添加新租户后公共架构未访问 public_urls.py
- encryption - 弱加密:RSA 填充不足
- spring-boot - Selenium-Jupiter 通用 webdriver 设置未应用
- ssms - 只有在关闭查询窗口后才提交事务,为什么?
- c++ - 推导的模板 arg 和自动 arg 之间有什么区别吗?
- lisp - 使用从字符串读取时如何处理文件结尾错误?