对PostgreSQL Merge Join 的理解

开始

伪代码:

复制代码
http://momjian.us/main/writings/pgsql/optimizer.pdf

sort(outer);            
sort(inner);            
i = 0;            
j = 0;            
save_j = 0;            
while (i < length(outer))            
{            
    if (outer[i] == inner[j])        
        output(outer[i], inner[j]);    
            
            
    if (outer[i] <= inner[j] && j < length(inner))        
    {        
        j++;    
        if (outer[i] < inner[j])    
            save_j = j;
    }        
    else        
    {        
        i++;    
        j = save_j;    
    }        
}            
复制代码

上述描述中,可以把两列排序好的数组看成 由大到小排列。

 Merge Join 先要对各表各自排序,然后从各自的排序表中抽取数据,到另一个排序表中做匹配。
通常来讲,能够使用merge join的地方,hash join 更快。

验证:

复制代码
postgres=# EXPLAIN SELECT relname,nspname FROM pg_class join
        pg_namespace ON (pg_class.relnamespace = pg_namespace.oid);
                               QUERY PLAN                                
-------------------------------------------------------------------------
 Hash Join  (cost=1.14..16.02 rows=290 width=128)
   Hash Cond: (pg_class.relnamespace = pg_namespace.oid)
   ->  Seq Scan on pg_class  (cost=0.00..10.90 rows=290 width=68)
   ->  Hash  (cost=1.06..1.06 rows=6 width=68)
         ->  Seq Scan on pg_namespace  (cost=0.00..1.06 rows=6 width=68)
(5 rows)

postgres=# 



postgres=# set session enable_hashjoin=false;
SET
postgres=# EXPLAIN SELECT relname,nspname FROM pg_class join
        pg_namespace ON (pg_class.relnamespace = pg_namespace.oid);
                               QUERY PLAN                                
-------------------------------------------------------------------------
 Merge Join  (cost=23.90..28.28 rows=290 width=128)
   Merge Cond: (pg_namespace.oid = pg_class.relnamespace)
   ->  Sort  (cost=1.14..1.15 rows=6 width=68)
         Sort Key: pg_namespace.oid
         ->  Seq Scan on pg_namespace  (cost=0.00..1.06 rows=6 width=68)
   ->  Sort  (cost=22.76..23.49 rows=290 width=68)
         Sort Key: pg_class.relnamespace
         ->  Seq Scan on pg_class  (cost=0.00..10.90 rows=290 width=68)
(8 rows)

postgres=# 
复制代码

[作者:技术者高健@博客园  mail: luckyjackgao@gmail.com ]

改了 join 的顺序 对 结果也没有影响。

复制代码
postgres=# EXPLAIN SELECT relname,nspname FROM pg_namespace join
        pg_class ON (pg_class.relnamespace = pg_namespace.oid);
                               QUERY PLAN                                
-------------------------------------------------------------------------
 Merge Join  (cost=23.90..28.28 rows=290 width=128)
   Merge Cond: (pg_namespace.oid = pg_class.relnamespace)
   ->  Sort  (cost=1.14..1.15 rows=6 width=68)
         Sort Key: pg_namespace.oid
         ->  Seq Scan on pg_namespace  (cost=0.00..1.06 rows=6 width=68)
   ->  Sort  (cost=22.76..23.49 rows=290 width=68)
         Sort Key: pg_class.relnamespace
         ->  Seq Scan on pg_class  (cost=0.00..10.90 rows=290 width=68)
(8 rows)

postgres=# 
复制代码
复制代码
postgres=# EXPLAIN SELECT relname,nspname FROM pg_namespace,
        pg_class where (pg_class.relnamespace = pg_namespace.oid);
                               QUERY PLAN                                
-------------------------------------------------------------------------
 Merge Join  (cost=23.90..28.28 rows=290 width=128)
   Merge Cond: (pg_namespace.oid = pg_class.relnamespace)
   ->  Sort  (cost=1.14..1.15 rows=6 width=68)
         Sort Key: pg_namespace.oid
         ->  Seq Scan on pg_namespace  (cost=0.00..1.06 rows=6 width=68)
   ->  Sort  (cost=22.76..23.49 rows=290 width=68)
         Sort Key: pg_class.relnamespace
         ->  Seq Scan on pg_class  (cost=0.00..10.90 rows=290 width=68)
(8 rows)

postgres=# 
复制代码

结束




本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/archive/2012/11/08/2760677.html,如需转载请自行联系原作者

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值