
# Agg
#### 算子说明
Agg算子是用于执行聚集计算的算子, 支持3种策略处理：普通聚集（不分组只做聚集）、排序聚集和哈希聚集。排序聚集和哈希聚集因为涉及到分组，需要和group by搭配一起使用。排序聚集和哈希聚集的差别在于，排序聚集的输入必须是有序的，而哈希聚集则不关注输入的顺序性。必须说明即便是输入排好序的情况下，也不一定会选择排序聚集，因为哈希聚集可能会有更优的执行性能。
#### 典型场景
- 普通聚集： 只涉及到聚集计算，一般用于对表做总数统计，或者对某一列做行数或特性统计；在执行计划中体现是Aggregate关键字。
- 排序聚集：输入元组是已经排好序的，或分组键恰好是有序列，则可能会选择排序聚集；在执行计划中体现是GroupAggregate关键字。
- 哈希聚集：业务中目前涉及的大部分场景，以及数据无序情况下的聚集计算；在执行计划中体现是HashAggregate关键字。
 
#### 示例
**示例1：**普通聚集。
```
--数据准备。 
gaussdb=# DROP TABLE IF EXISTS student;
gaussdb=# CREATE TABLE student(id integer, class_id integer, grade number); 
CREATE TABLE 
gaussdb=# INSERT INTO student VALUES(generate_series(1,50), 1, floor(100 * random())); 
INSERT 0 50 
gaussdb=# INSERT INTO student VALUES(generate_series(51,100), 2, floor(100 * random())); 
INSERT 0 50 
gaussdb=# INSERT INTO student VALUES(generate_series(101,150), 3, floor(100 * random())); 
INSERT 0 50 
gaussdb=# INSERT INTO student VALUES(generate_series(151,200), 3, floor(100 * random())); 
INSERT 0 50
-- 执行结果。 
gaussdb=# EXPLAIN SELECT count(*) FROM student; 
                                QUERY PLAN
---------------------------------------------------------------------------
 Aggregate  (cost=13.23..13.27 rows=1 width=8)
   ->  Streaming (type: GATHER)  (cost=13.23..13.27 rows=2 width=8)
         Node/s: All datanodes
         ->  Aggregate  (cost=13.16..13.17 rows=2 width=8)
               ->  Seq Scan on student  (cost=0.00..13.13 rows=20 width=0)
(5 rows)
```
**示例2：**排序聚集。
```
gaussdb=# SET enable_hashagg = off;
SET
gaussdb=# EXPLAIN SELECT id, count(class_id) FROM student GROUP BY id ORDER BY id; 
                                QUERY PLAN
---------------------------------------------------------------------------
 Streaming (type: GATHER)  (cost=14.00..14.54 rows=21 width=16)
   Merge Sort Key: id
   Node/s: All datanodes
   ->  GroupAggregate  (cost=13.37..13.60 rows=21 width=16)
         Group By Key: id
         ->  Sort  (cost=13.37..13.40 rows=21 width=8)
               Sort Key: id
               ->  Seq Scan on student  (cost=0.00..13.13 rows=20 width=8)
(8 rows)
```
**示例3：**哈希聚集。
```
gaussdb=# SET enable_hashagg = on;
gaussdb=# SET enable_enable_fast_query_shipping = on;
gaussdb=# EXPLAIN SELECT id, avg(grade) FROM student GROUP BY id;  
                                 QUERY PLAN
----------------------------------------------------------------------------
 Streaming (type: GATHER)  (cost=14.00..14.57 rows=21 width=68)
   Node/s: All datanodes
   ->  GroupAggregate  (cost=13.37..13.63 rows=21 width=68)
         Group By Key: id
         ->  Sort  (cost=13.37..13.40 rows=21 width=36)
               Sort Key: id
               ->  Seq Scan on student  (cost=0.00..13.13 rows=20 width=36)
(7 rows)
--删除。
gaussdb=# DROP TABLE student;
```
上述示例中，Agg算子输出信息如下所示。
| 信息名称           | 含义                                 |
|:---|:---|
| Aggregate      | 普通的聚集算子名称，代表不分组只做聚集。               |
| GroupAggregate | 排序聚集算子名称，代表输入元组是已经排好序的，或分组键恰好是有序列。 |
| HashAggregate  | 哈希聚集算子名称，大部分场景，以及数据无序情况下的聚集计算。     |
   
