用于对数据进行分组的算法有 HASH 算法和 MERGE 算法,因此根据算法可以将 GROUP BY 算子分为两种:HASH GROUP BY 和 MERGE GROUP BY。执行计划生成时根据 SQL 优化器对于两种算子的代价评估,来选择使用哪种 GROUP BY 算子。

    对于普通的聚合函数(SUM/MAX/MIN/AVG/COUNT/STDDEV)也是通过分配 GROUP BY 算子来完成,而对于只有聚合函数而不含有 GROUP BY 的 SQL,分配的是 SCALAR GROUP BY 算子,因此 GROUP BY 算子又可以分为三种:SCALAR GROUP BY、HASH GROUP BY 和 MERGE GROUP BY。

    示例 1:含 SCALAR GROUP BY 算子的执行计划

    上述示例中,Q1 查询的执行计划展示中的 outputs & filters 中详细列出了 SCALAR GROUP BY 算子的输出信息如下:

    示例 2:含 HASH GROUP BY 算子的执行计划

    上述示例中,Q2 查询的执行计划展示中的 outputs & filters 详细列出了 HASH GROUP BY 算子的输出信息如下:

    信息名称

    含义

    output

    该算子输出的表达式。

    filter

    该算子上的过滤条件。

    group

    需要进行分组的列。

    例如,Q2 查询是 HASH GROUP BY 算子,所以为 nil。

    agg_func

    所涉及的聚合函数。

    例如,Q2 查询中计算表 t1 的 c1 列之和,因此为 。

    说明

    HASH GROUP BY 算子将会保证在执行时采用 HASH 算法进行分组。

    示例 3:含 MERGE GROUP BY 算子的执行计划

    上述示例中,Q3 查询的执行计划展示中的 outputs & filters 中详细列出了 MERGE GROUP BY 算子的信息,可以看出相同的 SQL 生成执行计划时选择了 MERGE GROUP BY 算子,其算子基本信息都是相同的,最大的区别是在执行的时候选择的分组算法不一样。同时,这里的 2 号算子 TABLE SCAN 返回的结果是一个无序结果,而 GROUP BY 算法采用的是 MERGE GROUP BY,因此必须分配一个 SORT 算子。

    注意

    NO_USE_HASH_AGGREGATION 和 USE_HASH_AGGREGATION 的 HINT 可以用于控制 GROUP BY 算子选择何种算法进行分组。