原生功能

原生的Greenplum内核不带有RoaringBitmap插件,开源社区实现了该功能,从而使得Greenplum可以支持RoaringBitmap类型。但该版本对于多阶段的聚合,并没有将聚合做到计算节点,而是实现为在主节点gathermotion再聚合,从而导致聚合性能不佳。

从SQL执行计划也可以看出,原生方式下的RoaringBitmap实现,采用的是主节点上的单阶段聚合,这也成为了我们可以进行性能优化的一个方面。

我们针对聚合操作进行了优化并改进,使得聚合操作采用多阶段聚合的方式实现,进一步提升RoaringBitmap在阿里云RDS实际业务中的性能。改进后的具体实现逻辑如下:

我们通过在从节点完成一阶段聚合操作,再由主节点完成二阶段聚合,从而充分利用从节点自身计算性能,采用多阶段方式,提高聚合操作性能。 改进后的执行计划为多阶段方式执行。

  1. QUERY PLAN
  2. -----------------------------------------------------------------------------------
  3. Aggregate (cost=1.08..1.09 rows=1 width=32)
  4. -> Gather Motion 3:1 (slice1; segments: 3) (cost=1.01..1.06 rows=1 width=32)
  5. -> Aggregate (cost=1.01..1.02 rows=1 width=32)
  6. -> Seq Scan on t1 (cost=0.00..1.01 rows=1 width=40)
  7. (4 rows)

性能测试1

  • 表结构
  • 测试结果

pic

  • 结果分析

主节点个数为1,从节点个数为3,相较于不采用多阶段聚合方式,性能提升基本在2-3倍,其中rb_and_agg原生环境下在主节点聚合所有数据,优化后效果明显。

为进一步说明ARRAY长度的大小不会使得改进后的方案性能降低,进行了第二轮性能测试。

  • 表结构
  1. CREATE TABLE t1 (id integer, bitmap roaringbitmap);
  2. INSERT INTO t1 SELECT GENERATE_SERIES(1,1000000),RB_BUILD(ARRAY(SELECT *FROM GENERATE_SERIES(1,10000)));
  • 测试结果
  • 结果分析

主节点个数为1,从节点个数为3,相较于不采用多阶段聚合方式,性能提升基本在2-3倍。其中rb_and_agg与rb_and_cardinality_agg执行时间超过10分钟,为方便构建测试结果图,取10w毫秒。

部署方法

创建插件

创建测试表

  1. postgres=# create table t1 (id integer, bitmap roaringbitmap);
  2. NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table.
  3. CREATE TABLE

插入测试数据

  1. postgres=# select rb_or_agg(bitmap) from t1;
  2. rb_or_agg
  3. --------------------------------------------------------------------------------------------------------------------------------------------
  4. :0\000\000\001\000\000\000\000\000\011\000\020\000\000\000\001\000\002\000\003\000\004\000\005\000\006\000\007\000\010\000\011\000\310\000
  5. (1 row)
  6. rb_or_agg
  7. --------------------------------------------------------------------------------------------------------------------------------------------
  8. :0\000\000\001\000\000\000\000\000\011\000\020\000\000\000\001\000\002\000\003\000\004\000\005\000\006\000\007\000\010\000\011\000\310\000
  9. (1 row)
  10. postgres=# select rb_and_agg(bitmap) from t1;
  11. rb_and_agg
  12. --------------------------------------------------------------------------------------------------------------------------------------------
  13. :0\000\000\001\000\000\000\000\000\011\000\020\000\000\000\001\000\002\000\003\000\004\000\005\000\006\000\007\000\010\000\011\000\310\000
  14. (1 row)
  15. postgres=# select rb_xor_agg(bitmap) from t1;
  16. rb_xor_agg
  17. --------------------------------------------------------------------------------------------------------------------------------------------
  18. :0\000\000\001\000\000\000\000\000\011\000\020\000\000\000\001\000\002\000\003\000\004\000\005\000\006\000\007\000\010\000\011\000\310\000
  19. postgres=# select rb_build_agg(id) from t1;
  20. rb_build_agg
  21. --------------------------------------------------------------------
  22. (1 row)
  23. postgres=# select rb_or_cardinality_agg(bitmap) from t1;
  24. rb_or_cardinality_agg
  25. -----------------------
  26. 10
  27. (1 row)
  28. postgres=# select rb_and_cardinality_agg(bitmap) from t1;
  29. rb_and_cardinality_agg
  30. ------------------------
  31. 10
  32. (1 row)
  33. postgres=# select rb_xor_cardinality_agg(bitmap) from t1;
  34. rb_xor_cardinality_agg
  35. ------------------------
  36. 10

我们将Greenplum原生RoaringBitmap插件进行了优化,增加了对聚合操作的多阶段执行处理,提升了RoaringBitmap多阶段聚合操作的执行性能。