数据库之Agg
select c2, avg(c1) from t1 group by c2 order by c3;
Agg(Aggregate)聚合操作, 表示按照 GROUP BY 指定列对输入数据进行聚合计算,或者不分组、对所有数据进行聚合计算。
常见的聚集函数:
- count
- sum
- avg
- max
- min
- ...
实现方式
不同的实现方式,可以使用不同的XO来完成,这里我们就可以分成三种XO
PlainAgg
简单Agg,不分组的聚集运算,会对整个数据进行聚集运算。
- 按行读入数据,对其进行聚集函数的运算;
- 当数据读完,得到聚集运算结果;
HashAgg
利用Hash表实现聚集运算,会对输入的数据,进行分组,而后进行计算得到结果。
- 根据输入行的分组列(group by)的值,通过Hash找到对应的分组;
- 按照指定的聚集函数,对该行进行聚集运算;
- 重复以上步骤处理所有的输入行,最后得到聚集结果;
SortAgg
基于分好组的有序的输入数据,对各个分组依次完成计算得到结果。
- 保证输入的数据按照指定的分组列排序;
- 按行读入数据,如果分组为当前计算的分组,则对其进行聚集运算;
- 否则,如果分组与当前计算的分组不同,则得到当前分组的聚集运算结果;
区别
- PlainAgg 为最基础的运算,对输入的所有数据进行累加,不涉及性能与内存开销问题
- HashAgg 由于需要对所有的数据进行分组,同时处理多个分组,因此可能会消耗较大的内存,乃至使用外存模式进行计算,可能会造成严重的性能问题,适用于
中小分组数目
的计算模式 - SortAgg 基于有序数据进行计算,每次只需要处理一个分组,内存消耗很小,切开销稳定,适用于
大分组数目
的计算模式
以上是Agg的具体实现算法的区别,下面LogicPlan看到的Agg,是逻辑计划如何安排各个XO实现这个分布式的聚集运算的方式。
LogicPlan区分
NormalAgg
普通的分布式执行方式,通常会选择使用SortAgg。eg:group by 常量
第一层将数据Hash送出从而达到分组效果;
第二层对不同的分组进行Agg运算;
第三层将各个分组的Agg运算结果汇总;
MultiAgg
多次进行Agg运算
第一层直接基于原始数据进行Agg运算,即每个Agg输出结果是混合各个不同分组的结果;
第二层对第一层的Agg结果进行第二次Agg运算,得到最终结果;
SemiAgg
结合NormalAgg和MultiAgg的特点,为最常用的执行方式;
当MultiAgg进行执行时,如果第一层数据的K值(分组)较高,那么第一层的Agg运算就失去了意义,最终还是要第二层基于所有数据进行计算,此时SemiAgg结合前两种方式得到执行方式如下: