南大通用GBase 8a针对group列唯一值多的延迟聚合优化参数

GBase 8a在做非Hash列的group时,默认策略是将各个节点的数据先在本地group后,再将结果发到临时表做二次聚合。此方案在聚合列唯一值少,聚合结果行数相比原始数据行数有明显降低时是非常适合的,但如果聚合结果没有降低,比如1000万行聚合后999万行,汇总到临时表后二次聚合,结果还是在999万行,则第一次的本地聚合就出现了资源浪费。GBase 8a提供了一个可选参数,通过延迟聚合来提升性能。

参数

gcluster_delayed_group_by_optimize

说明

是否针对group开启延迟聚合,默认值0, 不开启。 设置为1开始

延迟聚合,就是不在本地做group后再发送数据,而是直接发送数据到临时表,在临时表做最后的聚合。

该参数对group列不包含hash分布列时才有效。

执行计划

如下是随机分布表的普通执行计划。

可以看到00步骤时,先做了本地group,然后将结果根据id列做了分发,01步骤对临时表做了最终的group聚合并返回。

整体看,group了2次,一次本地,一次临时表。

gbase> show create table tt;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                      |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tt    | CREATE TABLE "tt" (
  "id" int(11) DEFAULT NULL,
  "id3" int(11) DEFAULT NULL,
  "id2" int(11) DEFAULT NULL,
  "name" varchar(100) DEFAULT NULL
) ENGINE=EXPRESS DEFAULT CHARSET=utf8 TABLESPACE='sys_tablespace' |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (Elapsed: 00:00:00.00)

gbase> explain select id,count(*) from tt group by id;
+----+--------------+-----------+---------+-------------+
| ID | MOTION       | OPERATION | TABLE   | CONDITION   |
+----+--------------+-----------+---------+-------------+
| 01 | [RESULT]     |  Step     | <00>    |             |
|    |              |  GROUP    |         | GROUP BY id |
| 00 | [REDIST(id)] |  Table    | tt[DIS] |             |
|    |              |  GROUP    |         | GROUP BY id |
+----+--------------+-----------+---------+-------------+
4 rows in set (Elapsed: 00:00:00.01)

开启延迟group的执行计划。

00步骤,将本地数据直接根据id列做了重分布到临时表,01步骤完成计算并返回结果。、

整体只做了1次group。

gbase> set gcluster_delayed_group_by_optimize=1;
Query OK, 0 rows affected (Elapsed: 00:00:00.01)

gbase> explain select id,count(*) from tt group by id;
+----+--------------+-----------+---------+-------------+
| ID | MOTION       | OPERATION | TABLE   | CONDITION   |
+----+--------------+-----------+---------+-------------+
| 01 | [RESULT]     |  Step     | <00>    |             |
|    |              |  GROUP    |         | GROUP BY id |
| 00 | [REDIST(id)] |  Table    | tt[DIS] |             |
+----+--------------+-----------+---------+-------------+
3 rows in set (Elapsed: 00:00:00.00)

总结

针对group后数据行数比例,如果很高,可以打开这个参数测试效果。支持session设置,以及hint方式。

参考 https://www.gbase8.cn/8995#SESSION%E5%8F%82%E6%95%B0hint

具体性能提升,要以额外1次的group性能消耗,对比分发更多数据的消耗,以实际对比为准。