AnalyticDB MySQL版的SQL诊断功能可以对SQL查询进行Query、Stage和算子(Operator)级别的信息统计,再在统计信息的基础上进行诊断并提供调优建议。本文介绍如何查看和分析算子级别诊断结果。
诊断结果类型
聚合算子聚合度低
- 问题
聚合算子的聚合度一般指GROUP BY分组聚合操作中的输入数据量和输出数据量的比值(即InputDataSize和OutputDataSize的比值),该值越小表明聚合度越低,聚合效果越差。在AnalyticDB MySQL版中,分组聚合操作一般分为两步:初步聚合(PARTIAL)和最终聚合(FINAL)。如果聚合算子分组的个数较多,会导致聚合度低,那么在第一步的初步聚合操作中,不但不能减少网络数据传输,反而会消耗大量的计算资源。
- 建议
可以考虑跳过初步聚合操作,直接在各个节点间对数据进行重分布,之后直接进行一次最终聚合。更多详情,请参见分组聚合查询优化。
过滤条件没有下推
- 问题AnalyticDB MySQL版在存储数据时默认对表的全部字段创建了索引,您可以在查询时使用这些索引来加速数据的过滤。但在如下场景中AnalyticDB MySQL版不会将过滤条件下推:
- 查询语句中使用了
no_index_columns
或filter_not_pushdown_columns
Hint,或集群使用了adb_config filter_not_pushdown_columns配置,导致过滤条件下推功能被关闭。 - 过滤条件中使用了函数(包括
cast
操作符)。 - 过滤条件中的相关字段没有索引(例如建表时指定了
no_index
关键字,或建表后执行DROP INDEX
删除了索引)。
- 查询语句中使用了
- 建议
- 如果是查询语句使用了Hint或集群使用了配置,导致的过滤条件下推功能关闭,请检查使用该Hint或配置的原因并判断是否可以取消该Hint或配置。更多详情,请参见过滤条件不下推。
- 如果是使用了函数,可以考虑是否直接使用该函数写入数据,而在查询时去掉函数。
- 如果是过滤条件中的相关字段没有索引导致过滤条件没有下推,那么需要检查没有索引的原因。
Join存在数据膨胀
- 问题
Join的数据膨胀率是Join的输出行数与Join的输入行数的比值,其中Join的输入行数为左表行数与右表行数之和。对于合理Join条件,一般Join的输出行数会小于输入行数,如果Join的输出行数大于输入行数,那么会存在Join数据膨胀的问题,Join数据膨胀会导致较多的计算资源和内存资源被占用,导致查询较慢。
- 建议
- 如果是数据本身特征导致的Join数据膨胀,例如左右表都大量存在的相同的值,可以考虑在表过滤阶段将这些相同值都过滤掉不参与Join。
- 如果是不优的Join顺序导致的数据膨胀,可以考虑手动调整Join顺序。调整方法,请参见手动调整Join顺序。
Join的右表过大
- 问题AnalyticDB MySQL版中的Join右表一般指Builder表,用于构建内存中的Hash结构或者Set结构。右表过大,可能会占用较多的内存资源,影响集群整体稳定性。导致Join右表过大的可能原因如下:
- SQL中有Left Join。由于Left Join的右表在执行过程中必须作为Builder表,所以如果Left Join的右表过大,必然占用较多内存资源。
- AnalyticDB MySQL版在预估左右表数据量时,由于统计信息过期等原因导致估计错误。
- 建议
建议将Left Join优化改写成Right Join。改写方法,请参见Left Join优化改写为Right Join。
存在Cross Join
- 问题
Cross Join,即没有Join条件的Join操作,输出的行数是左右两表行数的乘积。如果左右表都较大,会极大地影响AnalyticDB MySQL版集群的稳定性。
- 建议
考虑增加Join条件,消除Cross Join。
扫描算子读取字段个数较多
- 问题
扫描算子会在AnalyticDB MySQL版的存储层进行数据的过滤和明细数据的读取,如果SELECT的字段个数较多,需要读取的明细数据也较多,那么就会占用较大的磁盘I/O资源,影响AnalyticDB MySQL版集群整体稳定性。
- 建议
可以优化SQL语句,减少SELECT语句中不必要的字段。
表扫描数据量倾斜
- 问题
AnalyticDB MySQL版是分布式执行架构,大表的数据一般需要指定分布字段,数据写入时根据分布字段分散到不同的存储节点上。如果分布字段的值分布不均匀,那么数据存储在各个节点上时也会不均匀,最终导致数据读取时,各个节点在读取数据时存在时间上的长尾,影响最终的查询效果。
- 建议
通过选择合适的分布字段来减少表扫描数据量的倾斜。优化方法,请参见分布字段合理性诊断。
索引不高效
- 问题
AnalyticDB MySQL版在使用索引进行数据过滤时,若需要过滤的字段过滤度(即过滤算子的输出数据量和输入数据量的比值)较低时,使用索引不一定能获得预期的过滤效果。
- 建议
可以考虑不下推过滤条件,而在计算节点中直接执行过滤操作。更多详情,请参见过滤条件不下推。