本文介绍几种典型的慢查询相关的资源消耗问题。您可以通过查询详情页和VisualPlan定位慢查询带来的资源消耗,更多信息可参见如何诊断慢查询查询详情页面VisualPlan

消耗内存的慢查询

首先可以通过慢查询表来确定某个时间段内耗时较大的查询,然后打开查询详情页面,在详情页的Stage级别统计信息处,根据Peak Memory字段排序,找到Peak Memory较大的Stage,然后打开VisualPlan,在VisualPlan找到对应的Stage,和SQL语句结合判断内存消耗较大的算子。

一般消耗内存较大的情况包括:
  • Stage中有group by操作,并且group by的字段唯一值较多,会导致在计算过程中使用较大内存进行group by字段值的缓存。
  • Stage中有join操作。在使用hash的方式进行join时会把某张表的数据缓存到内存中,所以如果被缓存在内存中的表较大,会占用较多内存。
  • Stage中有sort操作。在执行数据的排序时,会把数据缓存到节点中,所以如果需要排序的数据量较大,会占用较多内存。
  • Stage中有window操作。在执行开窗操作时,会把数据缓存在内存中,如果需要执行开窗的数据量较大,会占用较多内存。

消耗CPU的慢查询

首先可以通过慢查询表来确定某个时间段内CPU消耗较大的查询,然后打开查询详情页面,在详情页的Stage级别统计信息处,根据Operator Cost字段排序,找到Operator Cost较大的Stage,然后打开VisualPlan,在VisualPlan找到对应的Stage,和SQL语句结合进行CPU消耗较大的算子的判断。

一般消耗CPU较大的情况包括:
  • 过滤条件没有下推到存储层。ADB在创建表时默认为所有字段创建了索引,如果可以使用索引进行过滤,可以极大的减少CPU的消耗,但是在某些情况下,例如在过滤条件中使用了function,会导致查询条件无法使用索引,ADB需要对每条扫描上来的数据执行过滤,此时会导致占用较多CPU资源。
  • join中带有过滤条件。如果join中带有过滤条件,ADB会先对两表执行join,然后对join后的数据执行过滤,此时无法使用索引,如果join后产生的数据量较大,那么过滤操作会消耗较大的CPU资源。
  • join时没有指定join的criterion。没有指定criterion的join,会对左右两表执行笛卡尔积运算,产生的数据量行数是左右两表数据行数的乘积,该类操作会带来较大的CPU资源消耗。

消耗磁盘IO的慢查询

首先可以通过慢查询表来确定某个时间段内Scan Time较大的查询,然后打开查询详情页面,在详情页的Stage级别统计信息处,根据Scan Time字段排序,找到Scan Time较大的stage,然后打开VisualPlan,在VisualPlan中找到对应的Stage,根据Tablescan算子的输入行数判断某个表是否存在大量的数据扫描。

一般消耗磁盘IO较大的问题包括:
  • 过滤条件的筛选率较低,会导致使用索引的效率不高。
  • 过滤条件没有下推,导致对源表进行了全表扫描。
  • 过滤条件下推,但是过滤条件设置的范围较大,仍然有大量数据被扫描。
  • 扫描的二级分区较多。