关联数据在不一样节点上,对于普通关系型数据库来讲,是没法进行链接的。关联的数据须要经过网络流入到一个节点中进行计算,这样就须要发生数据迁移。数据迁移有广播和重分布两种。在GP中,每个广播或重分布会产生一个切片,每个切片在每一个数据节点上都会对应发起一个进程来处理该slice负责的数据,上一层负责该slice的进程会读取下级slice广播或重分布的数据,而后进行相应的计算。html
当两张表关联的时候,若是有一张表的关联键不是分布键,那么就会发生表的广播或者重分布,将数据移动到一个节点上进行关联,从而得到数据。
分布式的关联有两种:
单库关联:关联键与分布键一致,只须要但单个库关联后获得结果便可。
跨库关联:关联键与分布键不一致,数据须要从新分布。转换成单库关联,从而实现表的关联。数据库
表关系以下:网络
表A
字段:id,id2
分布键:id
数据量:M分布式
表B
字段:id,id2
分布键:id
数据量:Nhtm
内链接blog
状况1:进程
select * from A,B where A.id=B.id;
分布键与关联键相同,属于单库关联,不会形成广播或者重分布。select
状况2:数据
select * from A,B where A.id=B.id2;
表A的关联键是分布键,表B的关联键不是分布键,那么能够经过两种凡是来实现关联。
1. 将表B按照id2字段将数据重分布到一个节点上,而后再与表A进行关联。重分布的数据量是N。
2. 将表A广播,每个节点都放一份全量数据,而后再与表B关联获得结果。广播的数据量是M*节点数。
因此,当N>M*节点数的时候,选择表A广播,不然选择B重分布。关系型数据库
状况3:
select * from A,B where A.id2=B.id2;
两个表的关联键与分布键都不同,那么还有两种作法:
1. 将表A与表B按照id2字段,将数据重分布到每一个节点,重分布的代价是M+N。
2. 将其中一张表广播后再关联,固然选取小表广播,代价小。广播的代价是min(M,N)*节点数。
因此当M+N>min(M,N)*节点数的时候,选择小表广播,不然选择两个表都重分布。
左链接
状况1:
select * from A left join B on A.id=B.id;
单库关联,不涉及数据库跨库关联。
状况2:
select * from A left join B on A.id=B.id2;
因为左表的分布键是关联键,鉴于左链接的性质,不管表B数据量多大,都必须将表B按照字段id2重分布数据。
状况3:
select * from A left join B on A.id2=B.id;
左表的关联键不是分布键,因为左链接A表确定不是被广播的,因此有两种方式。
1. 将表A按照id2重分布数据,转换成状况A,代价为M。
2. 将表B广播,代价为N*节点数。
状况4:
select * from A left join B on A.id2=B.id2;
有两种处理方式。
1. 将表A与表B都按照id2字段将数据重分布一遍以,转换成状况1,代价是M+N。
2. 表A不能被广播,只能将表B广播,代价是N*节点数。
全链接
状况1:
select * from A full outer join B on A.id=B.id;
关联键是分布键,在GP中全链接只能采用Merge Join来实现。
状况2:
select * from A full outer join B on A.id=B.id2;
将不是关联键不是分布键的表重分布数据,转换成状况1解决。不管A、B大小分别为多少,为了实现全链接,不能讲表广播,只能是重分布。
状况3:
select * from A full outer join B on A.id2=B.id2;
将两张表都重分布,转换成状况1进行处理。
《Greenplum企业应用实战》
(原文地址:http://www.jpblog.cn/greenplum-%E6%89%A7%E8%A1%8C%E8%AE%A1%E5%88%92%E4%B9%8B%E5%B9%BF%E6%92%AD%E4%B8%8E%E9%87%8D%E5%88%86%E5%B8%83.html)