GreenPlum的并行查询优化策略

1、GreenPlum这种share nothing的架构:


良好的发挥了廉价PC的作用。自此I/O不在是DW的瓶颈,相反网络的压力会大很多。但是greenplum的查询优化策略能够避免尽量少的网络交换。对于初次接触greenplum的人来说,肯定耳目一新。

2、greenplum的查询优化器
     greenplum的查询优化器负责将SQL解析成每个节点(segments)所要走的物理执行计划。也是基于成本的优化策略:评估若干个执行计划,找出最有效率的一个。主节点master负责SQL解析和执行计划的生成。
 不像传统的查询优化器,Greenplum的查询优化器必须全局的考虑整个集群,在每个候选的执行计划中考虑到节点间移动数据的开销。一旦执行计划确定,比如有join,那么join是在各个节点分别进行的(本机只和本机的数据join)。所以它的查询很快。

 3、查询计划包括了一些传统的操作,比如:扫描、Join、排序、聚合等等。

      greenplum中有三种数据的移动操作:
   A: Broadcast Motion (N:N) ,即广播数据,每个节点向其他节点广播需要发送的数据。
   B: Redistribute Motion (N:N) ,重新分布数据,利用join的列值hash不同,将筛选后的数据在其他segment重新分布。
   C: Gather Motion (N:1),聚合汇总数据,每个节点将join后的数据发到一个单节点上,通常是发到主节点master。


4、一个简单的例子:

explain select d.*,j.customer_id from data d join  jd1 j on d.partner_id=j.partner_id where j.gmt_modified> current_date -80;   
                                       QUERY PLAN                                          
----------------------------------------------------------------------------------------   
 Gather Motion 88:1  (slice2)  (cost=3.01..939.49 rows=2717 width=59)   
   ->  Hash Join  (cost=3.01..939.49 rows=2717 width=59)   
         Hash Cond: d.partner_id::text = j.partner_id::text   
         ->  Seq Scan on data d  (cost=0.00..260.74 rows=20374 width=50)   
         ->  Hash  (cost=1.91..1.91 rows=88 width=26)   
               ->  Broadcast Motion 88:88  (slice1)  (cost=0.00..1.91 rows=88 width=26)   
                     ->  Seq Scan on jd1 j  (cost=0.00..1.02 rows=1 width=26)   
                           Filter: gmt_modified > ('now'::text::date - 80)  

执行计划执行从下至上:
    a, 在各个节点扫描自己的 jd1 表数据,按照条件过滤生成数据 rs
    b, 各节点将自己生成的 rs 依次发送到其他节点。( Broadcast Motion (N:N) , 即广播数据)
    c, 每个节点上的 data 表的数据,和各自节点上收到的 rs 进行 join 。这样就保证本机上的数据只和本机的数据 join 。
    d ,各节点将 join 后的结果发送给 master ( Gather Motion (N:1) )

由上面的执行过程可以看出, Greenplum 是将 rs 给每个含有 data 表数据的节点都发了一份的。
要是 RS 很大或者压根就没有过滤条件怎么办呢:

=> select count(*) from jd1;   
 count    
-------   
    20   
(1 row)  


=> select count(*) from data;   
 count     
--------   
 113367  

要是 rs 很大的话,广播数据 网络就会成为瓶颈。可以看出 greenplum 很聪明:
它是将小表广播到各个 segment 上。可以看出统计信息对于生成好的查询计划是何等重要。


5、下面看一个复杂点的例子: 


执行计划如下:


 

A,各个节点上 同时扫描各自的nation表数据,将各segment上的nation数据向其他节点广播(Broadcast Motion (N:N) )
B, 各个节点上 同时扫描各自customer数据,和收到的nation数据join 生成RS-CN
C,各个segment同时扫描自己orders表数据,过滤数据生成RS-O
D, 各个segment同时扫描 自己lineitem表数据,过滤生成RS-L
E,各个segment同时将各自RS-O和RS-L进行join 生成RS-OL,注意此过程不需要Redistribute Motion (N:N) ,重新分布数据,因为orders和lineitem的distribute column都是orderkey。这就保证了各自需要join的对象都是在各自的机器上,所以n个节点就开始并行join了。
F, 各个节点将自己在步骤E生成的RS-OL按照cust-key在所有节点间重新分布数据(Redistribute Motion (N:N),可以按照hash和range在节点间来重新分布数据,默认是hash ),这样每个节点都会有自己的RS-OL
G, 各个节点将自己在步骤B生成的RS-CN和自己节点上的RS-OL数据进行join,又是本机只和本机的数据进行join
H, 聚合,排序,发往主节点master


 
6、总结:
    Greenplum如何处理和优化一张大表和小表的join?
    Greenplum是选择将小表广播数据,而不是将大表广播。
 
    举例说明:表A 有10亿 (empno<pk>,deptno,ename),表B(deptno<pk>,dname,loc) 500条  join on  deptno
有11个节点:1 master+10 segment
 
    按照正常的主键列hash分布,每个segment节点上只会有1/10的A和1/10的表B。
 
     此时greenplum会让所有节点给其他节点发送各自所拥有的小表(B)1/10的数据,这样就保证了10个节点上,每个节点都有一份完整的表B的数据。此时 每个节点上1/10的A 只要和自己节点上的B进行Join 就OK。所以Greenplum并行处理能力惊人的原因就在这里。
 
     最终所有节点会将join的结果都发给主节点master,master负责和各种client(比如JDBC,GP client等等)的连接。可见统计信息十分重要,Greenplum通过统计信息来确定将哪张表进行(Broadcast Motion (N:N) ,即广播数据)。
 
       还有一种,对于列值倾斜的情况, 比如A 没有按照主键来hash分布,而是人为指定按照deptno的hash在各个节点上分布数据,若A中80%的数据 都是sales  (deptno=10)部门的。此时10个节点中,就会有一个节点上拥有了10亿×80%的数据,就算是将B表广播到其他节点了 也无济于事,因为计算的压力都集中在一台机器了。所以选择合适的列进行hash分布,也很关键。

转自:http://blog.163.com/jing_playboy/blog/static/7573622220123211040433/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值