查询性能改进
以下是影响 Amazon Redshift 查询性能的一些常见问题,以及诊断和解决这些问题的方法说明。
表统计数据缺失或过时
如果表统计信息缺失或过期,您可能会看到以下内容:
-
EXPLAIN 命令结果中存在警告消息。
-
STL_ALERT_EVENT_LOG 中存在缺失统计数据提醒事件。有关更多信息,请参阅 查看查询警报。
要修复此问题,请运行 ANALYZE。
嵌套循环
如果存在嵌套循环,您可能会在 STL_ALERT_EVENT_LOG 中看到嵌套循环提示事件。此外,您还可以通过运行确定具有嵌套循环的查询中的查询来识别此类事件。有关更多信息,请参阅 查看查询警报。
要修复这一问题,请检查查询是否存在交叉联接,尽量将其删除。交叉联接是无联接条件的联接,它会导致对两个表执行笛卡尔积操作。它们通常作为嵌套循环联接运行,这是最慢的可能联接类型。
哈希联接
如果存在哈希联接,您可能会看到以下内容:
-
查询计划中的哈希和哈希联接操作。有关更多信息,请参阅 分析查询计划。
-
SVL_QUERY_SUMMARY 中 maxtime 值最大的段中的 HJOIN 步骤。有关更多信息,请参阅 使用 SVL_QUERY_SUMMARY 视图。
要修复这一问题,您可以采取以下几种方法:
-
重写查询,尽可能使用合并联接。为此,您可以指定既是分配键又是排序键的联接列。
-
如果 SVL_QUERY_SUMMARY 中 HJOIN 步骤的行数字段值较查询中最终 RETURN 步骤中的行数值大得多,请确认您能否重写查询以基于唯一的列进行联接。当查询未联接唯一列(如主键)时,该列会增加联接中涉及的行数。
虚影行或未提交的行
如果存在虚影行或未提交的行,您可能会在 STL_ALERT_EVENT_LOG 中看到一个提示事件,指示虚影行过多。有关更多信息,请参阅 查看查询警报。
要修复这一问题,您可以采取以下几种方法:
-
检查 Amazon Redshift 控制台的加载选项卡,以便对任何查询表进行活动加载操作。如果您发现有处于活动状态的加载操作,请等待这些操作完成,然后再执行操作。
-
如果没有活动加载操作,请对查询表运行 VACUUM 以移除已删除的行。
未排序或排序错乱的行
如果存在未排序或排序错误的行,您可能会在 STL_ALERT_EVENT_LOG 中看到一个非常有选择性的筛选提示事件。有关更多信息,请参阅 查看查询警报。
您也可以运行确定具有数据偏斜或未排序行的表中的查询以检查查询中的任意表是否包含大片未排序的区域。
要修复这一问题,您可以采取以下几种方法:
非最优数据分配
如果数据分配不佳,您可能会看到以下内容:
-
STL_ALERT_EVENT_LOG 中存在顺序执行、大型广播或大型分配提醒事件。有关更多信息,请参阅 查看查询警报。
-
对于给定步骤,处理的切片数与行数相差较大。有关更多信息,请参阅 使用 SVL_QUERY_REPORT 视图。
-
对于给定步骤,切片的处理时间相差较大。有关更多信息,请参阅 使用 SVL_QUERY_REPORT 视图。
如果上述条件均未满足,您还可以查看查询中是否有任意表存在数据偏斜(运行确定具有数据偏斜或未排序行的表中的查询)。
要修复这一问题,请查看查询中表的分布方式,看看有无任何可以改进之处。在进行任何更改之前,请务必权衡查询的性能及其他重要查询和系统的整体性能。有关更多信息,请参阅 用于优化查询的数据分配。
分配给查询的内存不足
如果为查询分配到的内存不足,您可能会看到 SVL_QUERY_SUMMARY 中存在一个 is_diskbased
值为真的步骤。有关更多信息,请参阅 使用 SVL_QUERY_SUMMARY 视图。
要修复这一问题,请临时增加查询使用的查询槽的数目,以向其分配更多的内存。工作负载管理 (WLM) 在查询队列中预留与为查询设置的并发级别相等的槽数。例如,并发级别为 5 的队列拥有 5 个槽。分配给队列的内存平均分配到每个槽。将多个槽分配给一个查询可使该查询访问所有这些槽的内存。有关如何临时增加查询的插槽的更多信息,请参阅wlm_query_slot_count。
非最优 WHERE 子句
如果 WHERE 子句导致表扫描过多,您可能会在分段中看到在 SVL_QUERY_SUMMARY 中具有最高 maxtime
值的 SCAN 步骤。有关更多信息,请参阅 使用 SVL_QUERY_SUMMARY 视图。
要修复这一问题,请根据最大的表的主排序列向查询添加 WHERE 子句。这种方法有助于尽量减少扫描时间。有关更多信息,请参阅 设计表的 Amazon Redshift 最佳实践。
谓词限制性不足
如果您的查询具有限制性不足的谓词,您可能会在分段中看到在 SVL_QUERY_SUMMARY 中具有最高 maxtime
SCAN 步骤,且它的 rows
值比查询的最终 RETURN 步骤中的 rows
值高很多。有关更多信息,请参阅 使用 SVL_QUERY_SUMMARY 视图。
若要解决此问题,请尝试向查询添加谓词或使现有谓词更具限制性,以缩小输出范围。
极大结果集
如果查询返回极大的结果集,请考虑重写查询,使用 UNLOAD 将结果写入 Amazon S3。这种方法可充分利用并行处理的优势,从而提高 RETURN 步骤的性能。有关检查极大结果集的更多信息,请参阅使用 SVL_QUERY_SUMMARY 视图。
大型 SELECT 列表
如果您的查询有一个异常大的 SELECT 列表,您可能会看到 SVL_QUERY_SUMMARY 中的任何步骤的 bytes
值(与其他步骤相比)相对于 rows
值较高。bytes
值较大说明您选择了大量列。有关更多信息,请参阅 使用 SVL_QUERY_SUMMARY 视图。
要解决此问题,请查看您正在选择的列,并查看是否可以删除任何列。