对PostgreSQL 的 hash join 的原理的学习

开始

PostgreSQL 名人 momjian 的文章指出了其pseudo code:

复制代码
for (j = 0; j < length(inner); j++)
  hash_key = hash(inner[j]);
  append(hash_store[hash_key], inner[j]);
for (i = 0; i < length(outer); i++)
  hash_key = hash(outer[i]);
  for (j = 0; j < length(hash_store[hash_key]); j++)
    if (outer[i] == hash_store[hash_key][j])
      output(outer[i], inner[j]);
复制代码

为了看的更加清楚一点,加上自己的注释:

复制代码
//利用 inner 表, 来构造 hash 表(放在内存里)            
for (j = 0; j < length(inner); j++)            
{            
    hash_key = hash(inner[j]);        
    append(hash_store[hash_key], inner[j]);        
}            
            
//对 outer 表的每一个元素, 进行遍历            
for (i = 0; i < length(outer); i++)            
{            
    //拿到 outer 表中的  某个元素, 进行 hash运算, 得到其 hash_key 值        
    hash_key = hash(outer[i]);        
            
            
    //用上面刚得到的 hash_key值, 来 对 hash 表进行 探测(假定hash表中有此key 值)        
    //采用 length (hash_store[hash_Key])  是因为,hash算法构造完hash 表后,有可能出现一个key值处有多个元素的情况。        
    //例如:  hash_key 100 ,对应 a,c, e; 而  hash_key 200 , 对应 d;  hash_key 300, 对应 f;        
    //也就是说, 如下的遍历,其实是对 拥有相同 的 (此处是上面刚运算的,特定的)hash_key 值的各个元素的遍历        
            
    for (j = 0; j < length(hash_store[hash_key]); j++)        
    {        
        //如果找到了匹配值,则输出一行结果    
        if (outer[i] == hash_store[hash_key][j])    
            output(outer[i], inner[j]);
    }        
}            
复制代码

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

实践一下:

复制代码
postgres=# \d employee
          Table "public.employee"
 Column |         Type          | Modifiers 
--------+-----------------------+-----------
 id     | integer               | 
 name   | character varying(20) | 
 deptno | integer               | 
 age    | integer               | 
Indexes:
    "idx_id_dept" btree (id, deptno)

postgres=# \d deptment
           Table "public.deptment"
  Column  |         Type          | Modifiers 
----------+-----------------------+-----------
 deptno   | integer               | 
 deptname | character varying(20) | 

postgres=# 

postgres=# select count(*) from employee;
 count 
-------
1000
(1 row)

postgres=# select count(*) from deptment;
 count 
-------
102
(1 row)

postgres=# 
复制代码

执行计划:

复制代码
postgres=# explain select a.name, b.deptname from employee a, deptment b where a.deptno=b.deptno;
                               QUERY PLAN                                
-------------------------------------------------------------------------
 Hash Join  (cost=3.29..34.05 rows=1000 width=14)
   Hash Cond: (a.deptno = b.deptno)
   ->  Seq Scan on employee a  (cost=0.00..17.00 rows=1000 width=10)
   ->  Hash  (cost=2.02..2.02 rows=102 width=12)
         ->  Seq Scan on deptment b  (cost=0.00..2.02 rows=102 width=12)
(5 rows)

postgres=# 
复制代码

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于 hash join 算法实现涉及到具体的数据库系统,不同数据库系统的 hash join 实现也会有所不同。这里以 PostgreSQL 数据库为例,简单介绍一下其 hash join 的实现。 在 PostgreSQL 中,hash join 算法主要分为两个阶段:构建哈希表和使用哈希表进行连接操作。 构建哈希表的过程中,首先会根据连接条件,从被连接关系中选择一个关系作为内部关系,并以内部关系的 join key 为基准进行哈希,将哈希值相同的元组放到一个桶中。这样,内部关系中的所有元组就被分配到了不同的桶中。接着,遍历外部关系中的元组,对于每个元组,都会计算其 join key 的哈希值,并在哈希表中查找是否有和该元组 join key 哈希值相同的桶。如果有,则将该元组与桶中的所有元组进行比较,找到符合连接条件的元组组合。如果没有,则该元组与内部关系中所有元组都没有匹配项,会被过滤掉。 构建好哈希表后,就可以使用哈希表进行连接操作了。遍历外部关系中的元组,对于每个元组,都计算其 join key 的哈希值,并在哈希表中查找是否有和该元组 join key 哈希值相同的桶。如果有,则将该元组与桶中的所有元组进行比较,找到符合连接条件的元组组合。如果没有,则该元组与内部关系中所有元组都没有匹配项,会被过滤掉。 以上就是 PostgreSQL 中哈希连接的实现过程,具体的源码实现可以参考 PostgreSQL 的源码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值