hash连接

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hash连接相关的知识,希望对你有一定的参考价值。

简单回顾嵌套循环:

两个表关联,较小的表(指使用了过滤条件后结果集较小的表)称为驱动表或者外表(,另一个称为内表。在嵌套连接过程中,oracle首先读取驱动表的第一条数据,然后和内表进行比对,所以匹配的记录存放在结果集中,然后读取驱动表的下一条数据,重复上面的操作,直到驱动表的所以数据都处理了一遍。嵌套循环是一种从连接结果中提取第一批数据的最快捷方式。

在驱动表较小、或者内表的关联列上有唯一索引或高度可选的非唯一索引时,嵌套循环的效果一般会比较好。

在索引范围扫描中,如果需要访问的键值数超过大几百万时,就不建议使用索引范围扫描了,因为此时开销会呈几何数增长。因此,在使用嵌套循环的过程中,如果发现需要访问的键值数有大几百万(驱动表记录数*每条数据与内表关联需要访问的键值数),就应该考虑使用hash连接代替,如果是单表走的索引,则应该考虑走全表扫描。

 

本次小课堂分享的内容:

1、简单了解hash连接的流程;

2、了解hash连接的使用限制及使用场景;

 

hash连接的流程

对于什么是Hash算法原理?这个问题有点难度,不是很好说清楚,来做一个比喻吧:我们有很多的小猪,每个的体重都不一样,假设体重分布比较平均(我们考虑到公斤级别),我们按照体重来分,划分成100个小猪圈。 然后把每个小猪,按照体重赶进各自的猪圈里,记录档案。 好了,如果我们要找某个小猪怎么办呢?我们需要每个猪圈,每个小猪的比对吗? 当然不需要了。 我们先看看要找的这个小猪的体重,然后就找到了对应的猪圈了。 在这个猪圈里的小猪的数量就相对很少了。 我们在这个猪圈里就可以相对快的找到我们要找到的那个小猪了。 对应于hash算法。 就是按照hashcode分配不同的猪圈,将hashcode相同的猪放到一个猪圈里。 查找的时候,先找到hashcode对应的猪圈,然后在逐个比较里面的小猪。 所以问题的关键就是建造多少个猪圈比较合适。 如果每个小猪的体重全部不同(考虑到毫克级别),每个都建一个猪圈,那么我们可以最快速度的找到这头猪。缺点就是,建造那么多猪圈的费用有点太高了。 如果我们按照10公斤级别进行划分,那么建造的猪圈只有几个吧,那么每个圈里的小猪就很多了。我们虽然可以很快的找到猪圈,但从这个猪圈里逐个确定那头小猪也是很累的。 所以,好的hashcode,可以根据实际情况,根据具体的需求,在时间成本(更多的猪圈,更快的速度)和空间本(更少的猪圈,更低的空间需求)之间平衡。(摘自网络)

 

两个表做hash连接,较小的表作为驱动表(这里指运用了过滤条件后结果集较小的表),另一个表称为探测表。

hash函数的一个特性:相同值经过hash函数运算得到的hash code一定相同,不同值经过hash函数运算得到的hash code可能不同。

在两个表做hash连接的过程中,我们会对驱动表的关联列使用两个内置函数计算hash值,我们把这两个hash值分别记为hash_value_1和hash_value_2,我们将hash_value_1相同的记录存放在一个hash bulket中,这里注意hash bulket只需要记录该sql语句的查询列、关联列及hash_value_2即可。hash table由这些hash bulket组成。

 

最理想模式下的hash连接流程:

技术分享

optimal模式

optimal模式就是从驱动表上获取的结果集比较小,可以把整个hash table都建立在用户可以使用的内存区域里。

大致上分为以下几步:

1、利用连接列上的hash函数,将从驱动表上获取的结果集做成hash table存放在内存中,这里的hash bulket总是2的n次方。可以简单的把hash table看做内存里的一个大正方形,里面有很多小格子,驱动表的数据就分布在这些小格子里面,这些小格子就是hash bulket。

2、oracle开始读取探测表的数据,对每一个数据都做关联列上的hash函数(和驱动表的hash函数相同),定位到hash table中的hash bulket,找到hash bulket就进去看看有没有匹配的数据。

3、如果hash bulket里没有数据,则丢弃探测表中的这一行数据。如果有,则进一步查看里面的数据是否和探测表的这条记录匹配。

4、循环处理,直到处理完探测表中的所有记录,返回结果集。

 

hash连接的使用限制及使用场景:

1、hash连接种驱动表的关联列上的可选择性应当尽可能的好(取值分布比较均匀),因为这个可选择性会影响hash bulket中的记录数,而hash bulket中的记录数又会影响从从匹配数据的效率。因此一个hash bulket所包含的记录数过多,可能严重降低所对应的hash连接的执行效率。

2、hash连接只适用于CBO,且只能用于等值连接。

3、hash连接很适合于一个小表(结果集)与一个大表之间的连接,特别是小表关联列上的可选择性非常好的情况,此时耗费的时间可以近似看成全表扫描两个表耗费的时间。

4、当关联列上缺乏有效的索引,hash连接比嵌套循环更加有效。

 --整理自网络

以上是关于hash连接的主要内容,如果未能解决你的问题,请参考以下文章

数据库多表连接方式介绍-HASH-JOIN

数据库多表连接方式介绍-HASH-JOIN

Firebird hash join

多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP

深入理解Oracle表:三大表连接方式详解之Hash Join的定义,原理,算法,成本,模式和位图...

表连接方式