in 数据库 分布式数据库 ~ read.

数据库之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,不分组的聚集运算,会对整个数据进行聚集运算。

  1. 按行读入数据,对其进行聚集函数的运算;
  2. 当数据读完,得到聚集运算结果;

HashAgg

利用Hash表实现聚集运算,会对输入的数据,进行分组,而后进行计算得到结果。

  1. 根据输入行的分组列(group by)的值,通过Hash找到对应的分组;
  2. 按照指定的聚集函数,对该行进行聚集运算;
  3. 重复以上步骤处理所有的输入行,最后得到聚集结果;

SortAgg

基于分好组的有序的输入数据,对各个分组依次完成计算得到结果。

  1. 保证输入的数据按照指定的分组列排序;
  2. 按行读入数据,如果分组为当前计算的分组,则对其进行聚集运算;
  3. 否则,如果分组与当前计算的分组不同,则得到当前分组的聚集运算结果;

区别

  1. PlainAgg 为最基础的运算,对输入的所有数据进行累加,不涉及性能与内存开销问题
  2. HashAgg 由于需要对所有的数据进行分组,同时处理多个分组,因此可能会消耗较大的内存,乃至使用外存模式进行计算,可能会造成严重的性能问题,适用于中小分组数目的计算模式
  3. SortAgg 基于有序数据进行计算,每次只需要处理一个分组,内存消耗很小,切开销稳定,适用于大分组数目的计算模式

以上是Agg的具体实现算法的区别,下面LogicPlan看到的Agg,是逻辑计划如何安排各个XO实现这个分布式的聚集运算的方式。

LogicPlan区分

NormalAgg

普通的分布式执行方式,通常会选择使用SortAgg。eg:group by 常量
normalAgg
第一层将数据Hash送出从而达到分组效果;
第二层对不同的分组进行Agg运算;
第三层将各个分组的Agg运算结果汇总;

MultiAgg

多次进行Agg运算
MultiAgg
第一层直接基于原始数据进行Agg运算,即每个Agg输出结果是混合各个不同分组的结果;
第二层对第一层的Agg结果进行第二次Agg运算,得到最终结果;

SemiAgg

结合NormalAgg和MultiAgg的特点,为最常用的执行方式;
当MultiAgg进行执行时,如果第一层数据的K值(分组)较高,那么第一层的Agg运算就失去了意义,最终还是要第二层基于所有数据进行计算,此时SemiAgg结合前两种方式得到执行方式如下:
SemiAgg