HASH JOIN的模式

  hash join有三种工作模式,分别是optimal模式,onepass模式和multipass模式,分别在v$sysstat里面有对应的统计信息:

  SQL> select name, value from v$sysstat where name like '%workarea executions%';

optimal模式

  optimal模式就是从build table上获取的结果集比较小,可以把整个hash table都建立在用户可以使用的内存区域里。下面这张图就是用来描述optimal的hash join的:

optimal hash join大致上分为以下几步:

1. 首先利用做连接的列上的hash函数,把build table的结果集做成内存里的hash table,这里的hash bucket总是2的n次方,比如1024或4096。可以简单的把hash table看做内存里的一个大正方形,你面有很多小格子,而build table上的数据则是分散的分布在这些格子里面,而这些小格子就是hash bucket。

2. oracle开始读取probe table, 针对每一条数据都对做连接的列上使用hash函数,定位对应build table的相同值的hash bucket,找到相应的hash bucket后就到那个位置是去看有没有匹配的数据。这个过程叫做probing hash table。

3. 在检查bush bucket的时候,如果bucket里面没有数据,那么马上丢掉probe table的这一行。如果Bucket里面有数据,就要进一步检查里面的数据是否和proble table当前的这个数据匹配,这一步是很必要的。在我们前面介绍filter和hash cluster table的时候我们提过,hash函数存在一个冲突的问题,也就是不同的hash key完全有可能对应到相同的hash bucket里,所以当我们为probe table上的一个值定位到了一个hash bucket的时候,我们需要做进一步的检查,来看看这个bucket里面哪些数据是我们需要的,哪些数据是我们不需要的。 在理想的情况下,我们希望每一个hash bucket里面最多只有一个hash key的数据,因此往往hash bucket的个数是要比hash key的个数要多的。

onepass hash join模式

  我们知道optimal hash join发生在我们可以把整个hash table全部放在内存里的时候,从而所有的join操作都可以在内存里面完成,这是我们最理想的模式。但是,当我们的内存无法放下整个hash table,我们就不得不在onepass模式下进行hash join。

1. 首先,由于内存无法放下所有的hash table内容,那么就会导致有的hash bucket放在内存里,有的hash bucket放在磁盘上,但不管放在哪里,Oracle使用一个bitmap结构来反应这些bucket的状态,包括位置和是否有数据在里面。

2. 当我们的probe table对连接的列使用hash函数之后,先到bitmap上看看对应的bucket是不是为空,而过为空,这条数据就丢掉不管。如果不为空,还要看现 在这个bucket是在内存里还是在磁盘上。如果是在内存里,就直接访问这个bucket并检查是否有数据匹配,如果有匹配就返回这条查询结果。第二种情 况是如果要访问的这个bucket在磁盘上,这时候如果直接去磁盘上访问显然cost很大,所以oracle的处理方法是先把这个probe的数据放到一 边不管。顺便一提的是这个probe的值首先是会放在内存里,如果以后积累了一定量的其他probe上的数据之后,oracle会把这些数据批量的写入到 磁盘,这就是图上的dump probe partitions to disk。

3. 当我们把probe完整的扫描了一边之后,我们可能已经返回了一部分匹配的数据,但是我们现在在磁盘还有两部分没有处理的数据:build table的hash table的一部分数据和probe table的一部分数据,现在oracle就把这两部分数据重新做一次hash join(这时候会重新比较谁的结果集比较小,因此可能会出现原来的build table变成probe table,原来的probe table变为build table),然后返回最终的查询结果。这就是onepass hash join的大致过程。

multipass hash join模式

  最后,如果我们的内存特别小或者相对而言需要hash的数据特别大,hash join就会以最恶劣的方式执行:multipass hash join。如果说onepass是只需要多从磁盘做一次probe table的读取,那么multipass就需要做多次读取,这往往发生在可用内存和数据量相差很大的情况下。multipass hash join是我们需要尽量避免的东西

对HASH JOIN的一次优化:

  http://www.cnblogs.com/killkill/archive/2010/07/22/1782889.html

--整理自网络

Oracle 表的连接方式(2)-----HASH JOIN的基本机制3的更多相关文章

  1. Oracle 表的连接方式(2)-----HASH JOIN的基本机制2

    Hash算法原理 对于什么是Hash算法原理?这个问题有点难度,不是很好说清楚,来做一个比喻吧:我们有很多的小猪,每个的体重都不一样,假设体重分布比较平均(我们考虑到公斤级别),我们按照体重来分,划分 ...

  2. Oracle 表的连接方式(2)-----HASH JOIN的基本机制1

    我们对hash join的常见误解,一般包括两个: 第一个误解:是我们经常以为hash join需要对两个做join的表都做全表扫描 第二个误解:是经常以为hash join会选择比较小的表做buil ...

  3. Oracle 表的连接方式(1)-----Nested loop join和 Sort merge join

    关系数据库技术的精髓就是通过关系表进行规范化的数据存储,并通过各种表连接技术和各种类型的索引技术来进行信息的检索和处理. 表的三种关联方式: nested loop:从A表抽一条记录,遍历B表查找匹配 ...

  4. Oracle 表的连接方式

    1. 连接说明 ① Oracle一次只能连接两个表.不管查询中有多少个表,Oracle 在连接中一次仅能操作两张表. ② 当执行多个表的连接时,优化器从一个表开始,将它与另一个表连接:然后将中间结果与 ...

  5. 转:ORACLE的JDBC连接方式:OCI和THIN

    oracle的jdbc连接方式:oci和thin oci和thin是Oracle提供的两套Java访问Oracle数据库方式. thin是一种瘦客户端的连接方式,即采用这种连接方式不需要安装oracl ...

  6. Oracle 三种连接方式 NESTED LOOP HASH JOIN SORT MERGE JOIN

    NESTED LOOP: 对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择.在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,因此整个查询返回的结果集不能太大( ...

  7. oracle 表空管理方式(LMT)、ASSM段管理方式、一级位图块、二级位图块、三级位图块。

    今天是2013-12-16,今天和明天是我学习oracle生涯中一个特殊的日子.今天晚上进行了一下表空间管理方式的学习,在此记录一下笔记. 对于oracle数据库最小i/0单位是数据块,最想分配空间单 ...

  8. EF的表左连接方法Include和Join

    在EF中表连接常用的有Join()和Include(),两者都可以实现两张表的连接,但又有所不同. 例如有个唱片表Album(AlbumId,Name,CreateDate,GenreId),表中含外 ...

  9. SQLAlchemy(2):多表操作 & 连接方式及原生SQL

    一对多:ForeignKey multitb_models.py import datetime from sqlalchemy import create_engine # 引入 创建引擎 from ...

随机推荐

  1. css 默认样式

    body,textarea,input,select,option {font-size:12px;color:#333;font-family:Tahoma,Arial,sans-serif;} h ...

  2. 重构23-Introduce Parameter Object(参数对象)

    有 时当 使用 一个 包含 多 个 参 数 的 方 法 时 , 由 于参 数 过 多 会 导 致 可 读 性 严 重 下 降 , 如 : 有 时当 使用 一个 包含 多 个 参 数 的 方 法 时 , ...

  3. mac下为Apache 创建 .htaccess文件

    标签:mac   .htaccess 在设置固定链接时会提示如下的问题:   若您的 .htaccess 文件可写,我们可以自动修改它.但似乎它不可写,因此我们在下方列出了您 .htaccess 文件 ...

  4. page59-一种能够累加数据的ADT(可视化版本) [可用于数据挖掘可视化工具]

    public class VisualAccumulator VisualAccumulator() 创建一个累加器 void addDataValue(double val) 添加一个新的数据值 d ...

  5. codeforces 677B B. Vanya and Food Processor(模拟)

    题目链接: B. Vanya and Food Processor time limit per test 1 second memory limit per test 256 megabytes i ...

  6. hdu 3656 DLX

    思路:二分枚举建边,用DLX判断是否满足. #include<set> #include<cmath> #include<queue> #include<cs ...

  7. BZOJ 2879: [Noi2012]美食节 最小费用流 动态添边

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 324  Solved: 179[Submit][Status] ...

  8. Android简易注解View(java反射实现)

    一.引言 Android中通过findViewById在布局文件中找到需要的View,加入一个Activity里面有许多的View需要初始化,那将是一件很繁琐的事情.当然Google一下你会发现有很多 ...

  9. [转]移动App测试中的最佳做法

    Daniel Knott 用过各种不同编程语言和软件质量保证工具.他在软件开发和测试方面干了七年,自2010年起,他一直在德国汉堡的XING AG公司就职,几个项目里,比如XING调查和XING建议, ...

  10. Android之adb命令

    1.安装APK(如果加 -r 参数,保留已设定数据,重新安装filename.apk) adb install xxx.apk adb install -r xxx.apk 2.卸载APK(如果加 - ...