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性能消耗,对比分发更多数据的消耗,以实际对比为准。