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 bucket中,这里注意hash bucket只需要记录该sql语句的查询列、关联列及hash_value_2即可。hash table由这些hash bucket组成。
最理想模式下的hash连接流程:

optimal模式
optimal模式就是从驱动表上获取的结果集比较小,可以把整个hash table都建立在用户可以使用的内存区域里。
大致上分为以下几步:
1、利用连接列上的hash函数,将从驱动表上获取的结果集做成hash table存放在内存中,这里的hash bucket总是2的n次方。可以简单的把hash table看做内存里的一个大正方形,里面有很多小格子,驱动表的数据就分布在这些小格子里面,这些小格子就是hash bucket。
2、oracle开始读取探测表的数据,对每一个数据都做关联列上的hash函数(和驱动表的hash函数相同),定位到hash table中的hash bucket,找到hash bucket就进去看看有没有匹配的数据。
3、如果hash bucket里没有数据,则丢弃探测表中的这一行数据。如果有,则进一步查看里面的数据是否和探测表的这条记录匹配。
4、循环处理,直到处理完探测表中的所有记录,返回结果集。
hash连接的使用限制及使用场景:
1、hash连接种驱动表的关联列上的可选择性应当尽可能的好(取值分布比较均匀),因为这个可选择性会影响hash bucket中的记录数,而hash bucket中的记录数又会影响从从匹配数据的效率。因此一个hash bucket所包含的记录数过多,可能严重降低所对应的hash连接的执行效率。
2、hash连接只适用于CBO,且只能用于等值连接。
3、hash连接很适合于一个小表(结果集)与一个大表之间的连接,特别是小表关联列上的可选择性非常好的情况,此时耗费的时间可以近似看成全表扫描两个表耗费的时间。
4、当关联列上缺乏有效的索引,hash连接比嵌套循环更加有效。
--整理自网络
hash连接的更多相关文章
- sql 查询强制使用HASH连接性能测试比较
		
HASH JOIN 散列连接 hash join是CBO 做大数据集连接时的常用方式.优化器扫描小表(或数据源),利用连接键(也就是根据连接字段计算hash 值)在内存中建立hash表,然后扫描大表, ...
 - oracle 表连接 - hash join 哈希连接
		
一. hash 连接(哈希连接)原理 指的是两个表连接时, 先利用两表中记录较少的表在内存中建立 hash 表, 然后扫描记录较多的表并探測 hash 表, 找出与 hash 表相匹配的行来得到结果集 ...
 - oracle Hash Join及三种连接方式
		
在Oracle中,确定连接操作类型是执行计划生成的重要方面.各种连接操作类型代表着不同的连接操作算法,不同的连接操作类型也适应于不同的数据量和数据分布情况. 无论是Nest Loop Join(嵌套循 ...
 - SQL Tuning 基础概述06 - 表的关联方式:Nested Loops Join,Merge Sort Join & Hash Join
		
nested loops join(嵌套循环) 驱动表返回几条结果集,被驱动表访问多少次,有驱动顺序,无须排序,无任何限制. 驱动表限制条件有索引,被驱动表连接条件有索引. hints:use_n ...
 - Oracle 哈希连接原理
		
<基于Oracle的sql优化>里关于哈希连接的原理介绍如下: 哈希连接(HASH JOIN)是一种两个表在做表连接时主要依靠哈希运算来得到连接结果集的表连接方法. 在Oracle 7.3 ...
 - SQL连接操作符介绍(循环嵌套, 哈希匹配和合并连接)
		
今天我将介绍在SQLServer 中的三种连接操作符类型,分别是:循环嵌套.哈希匹配和合并连接.主要对这三种连接的不同.复杂度用范例的形式一一介绍. 本文中使用了示例数据库AdventureWorks ...
 - Oracle表的几种连接方式
		
1,排序 - - 合并连接(Sort Merge Join, SMJ) 2,嵌套循环(Nested Loops, NL) 3,哈希连接(Hash Join, HJ) Join是一种试图将两个表结合在一 ...
 - SQL Server三种表连接原理
		
在SQL Server数据库中,查询优化器在处理表连接时,通常会使用一下三种连接方式: 嵌套循环连接(Nested Loop Join) 合并连接 (Merge Join) Hash连接 (Hash ...
 - Nested Loop,Sort Merge Join,Hash Join
		
三种连接工作方式比较: Nested loops 工作方式是从一张表中读取数据,访问另一张表(通常是索引)来做匹配,nested loops适用的场合是当一个关联表比较小的时候,效率会更高. Merg ...
 
随机推荐
- [转]搭建高可用mongodb集群(二)—— 副本集
			
在上一篇文章<搭建高可用MongoDB集群(一)——配置MongoDB> 提到了几个问题还没有解决. 主节点挂了能否自动切换连接?目前需要手工切换. 主节点的读写压力过大如何解决? 从节点 ...
 - blade and soul races guide
			
Race Four races are available for those who wish to choose the path of martial arts: the careful Gon ...
 - Entity Framework – (复数)Plural and (单数)Singular 表名Table names
			
By default, the Entity Framework will assume that all of the names of your tables in your database a ...
 - bzoj3876: [Ahoi2014]支线剧情
			
神犇题解:http://blog.csdn.net/popoqqq/article/details/43024221 题意:给定一个DAG,1为起始点,任意一个点可以直接回到1,每条边有经过代价,求一 ...
 - 如何应用.NET中的消息队列服务
			
建立一个队列是应用MSMQ的第一步.您可以通过Windows计算机管理控制台中的消息队列选项完成这一操作,或者自己编程建立一个队列.列表A中的C#代码建立了一个新的私有MSMQ消息队列(如果不存在队列 ...
 - 1476. Lunar Code
			
http://acm.timus.ru/problem.aspx?space=1&num=1476 由于前一列对后一列有影响,所以需要保持前一列的状态, 但无需用状态压缩来保存(也保存不了) ...
 - React Native 一个组件styles BUG
			
'use strict'; var React = require('react-native'); var { StyleSheet, PanResponder, View, Text } = Re ...
 - 用ant组建测试框架
			
有时候由于公司网络或其它原因,无法采用maven,这时ant是一个比较理想的选择.以下是以ant为例,搭建一个测试框架 项目结构如下图: build.properties代码如下: # The sou ...
 - AngularJs的UI组件ui-Bootstrap分享(十)——Model
			
Model是用来创建模态窗口的,但是实际上,并没有Model指令,而只有$uibModal服务,创建模态窗口是使用$uibModal.open()方法. 创建模态窗口时,要有一个模态窗口的模板和对应的 ...
 - C++之虚函数和多态
			
干货较多-需要自己深思理解: C++支持两种多态性: 1.编译时多态性(静态绑定-早绑定) 在程序编译阶段即可以确定下来的多态性 通过使用 重载机制(重载函数)实现 (模板)http://blog.c ...