Greenplum广播与重分布原理
Tags: GreenPlum
简介
Greenplum的执行计划和PostgreSQL基本一致,但是在表关联的时候还是会有区别,因为greenplum中数据不同于pg,greenplum是将数据分布在多个节点上。所以当两表关联时关联列又不是表的分布键时就会出现表的广播和重分布。本文将详细介绍广播和重分布的区别及场景。
在此之前,我们需要先了解下在greenplum中表之间分布式关联有哪些类型?
表的分布式关联主要分为两大类:
1、单库关联,即表的关联键和分布键一致,所以只需要在单个库中得到结果后再关联即可,因此也不会涉及到广播和重分布;
2、跨库关联,即表的关联键和分布键不一致,因此数据需要重新分布来达到单库关联的效果,这也是本文主要讲解的地方。
对于跨库关联又分为两种情况:
2.1、一张表的关联键是分布列,另一张表不是;
2.2、两张表的关联键均不是分布列。
详细情况如下图所示(a、b两表中c1列是分布列):
示例
下面结合实例来讲解广播和重分布的原理及场景。
构建环境:
1 2 3 4 | postgres=# CREATE table a(c1 int,c2 int)distributed by(c1); CREATE TABLE postgres=# CREATE table b(c1 int,c2 int)distributed by(c1); CREATE TABLE |
现在主要来看看跨库关联的两种情况:
—情况一:a.c1=b.c2
即a表关联键是分布列,b表不是。这种情况可以通过两种方法来实现表的关联:
1、重分布:将b表按照c2字段将数据重新分布到每个节点上,然后再和a表关联。这种情况下重分布的数据量就是b表的数据量N;
2、广播:将a表上的数据进行广播,即每个节点都放一份全量数据,然后再和b表关联。这种情况下数据量大小就是a表数据量M * 节点数L。
综上,我们可以得出结论:
N > M L:选择广播;
N < =M L:选择重分布。
下面用实例来验证下:
—M = 20000,N = 15000,L=2:
1 2 3 4 | postgres=# insert into a select generate_series(1,20000),generate_series(1,20000); INSERT 0 20000 postgres=# insert into b select generate_series(1,15000),generate_series(1,15000); INSERT 0 15000 |
执行计划:重分布