本文介绍AnalyticDB MySQL版中几种典型的慢查询以及导致慢查询的原因。
消耗内存的慢查询
查询的峰值内存(Peak Memory)可以帮助您评估内存的消耗情况。通常来说,查询峰值内存越大,内存消耗越大。
您可以通过SQL诊断功能来检索某个时间段内执行耗时较长的查询,然后在查询属性或不同级别的诊断结果中查看目标查询的峰值内存。更多详情,请参见查看查询属性与诊断结果。
- Stage中有GROUP BY操作。
AnalyticDB MySQL会将GROUP BY字段的值缓存在内存中。如果GROUP BY的字段唯一值较多,就会占用较多内存。
- Stage中有JOIN操作。
在使用Hash方式进行Join时,AnalyticDB MySQL会把某张表的数据缓存到内存中。如果被缓存的表较大,就会占用较多内存。
- Stage中有SORT操作。
在执行数据排序时,AnalyticDB MySQL会把数据缓存到内存中。如果需要排序的数据量较大,就会占用较多内存。
- Stage中有窗口函数操作。
在执行窗口函数时,AnalyticDB MySQL会把数据缓存在内存中。如果需要执行窗口函数的数据量较大,就会占用较多内存。关于窗口函数的详情,请参见窗口函数。
消耗CPU的慢查询
查询的执行耗时(Time Consumed)可以帮助您评估CPU的消耗情况。通常来说,查询执行耗时越长,CPU消耗越大。
您可以通过SQL诊断功能来检索某个时间段内执行耗时较长的查询,然后在查询属性中查看目标查询的耗时。更多详情,请参见查看查询属性。
- 过滤条件没有下推到存储层。AnalyticDB MySQL在创建表时默认为所有字段创建了索引,使用索引进行过滤可以极大减少CPU资源的消耗,但是在某些场景下过滤条件没有下推。更多详情,请参见过滤条件没有下推。
- Join条件中带有过滤操作。如果Join中带有过滤条件,AnalyticDB MySQL会先对两表执行Join,再对Join后的数据执行过滤,此时的过滤无法使用索引。如果Join后产生的数据量较大,过滤操作就会消耗较大的CPU资源。
- Join时没有指定Join条件。如果没有指定Join条件,AnalyticDB MySQL会对左右两表执行笛卡尔积运算,产生的数据量行数是左右两表数据行数的乘积,该类操作会导致消耗较大的CPU资源。
消耗磁盘I/O的慢查询
查询的扫描行数(Scanned Rows)和扫描量(Amount of Scanned Data)可以帮助您评估磁盘I/O资源的消耗情况。通常来说,扫描行数和扫描量越多,磁盘I/O消耗越大。
您可以通过SQL诊断功能来检索某个时间段内执行耗时较长的查询,然后在查询属性或不同级别的诊断结果中查看目标查询的扫描行数和扫描量。更多详情,请参见查看查询属性与诊断结果。
- 过滤条件的数据筛选率较低,导致索引的使用效率不高,需要读取的索引量较大。
- 过滤条件没有下推,导致对源表进行了全表扫描。
- 过滤条件下推,但是过滤条件设置的范围较大,仍然有大量数据被扫描。
- 需要扫描的分区较多。通常情况下,分区越多意味着需要扫描的数据量越大。