哈希连接(hashjoin)
   访问次数:
驱动表和被驱动表都只会访问0次或1次。
   驱动表是否有顺序:有。
   是否要排序:否。
   应用场景: 1. 一个大表,一个小表的关联;
                         2. 表上没有索引;
                         3. 返回结果集比较大。

原理我们说的简单一点,先把驱动表的关联字段hash到PGA中(当然rowid也在PGA中),然后扫描被驱动表,取第一条数据,将关联的字段hash 一下探测PGA中的小表,如果匹配则关联,再取第二条........。

 下面我们来做个试验:

SQL> create table test1 as select * from dba_objects where rownum <=100;
SQL> create table test2 as select * from dba_objects where rownum <=1000;
SQL> exec dbms_stats.gather_table_stats(user,'test1');
SQL> exec dbms_stats.gather_table_stats(user,'test2');
SQL> alter session set statistics_level=all;

SQL> select /*+leading(t1) use_hash(t2)*/count(*)
      from test1 t1, test2 t2
     where t1.object_id = t2.object_id;
  COUNT(*)
----------
       100

SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  3f2mts0kt82u2, child number 0
-------------------------------------
select /*+leading(t1) use_hash(t2)*/count(*)   from test1 t1, test2 t2  where t1.object_id = t2.object_id
Plan hash value: 2544416891

----解释一下:

Starts为该sql执行的次数。
E-Rows为执行计划预计的行数。
A-Rows为实际返回的行数。A-Rows跟E-Rows做比较,就可以确定哪一步执行计划出了问题。
A-Time为每一步实际执行的时间(HH:MM:SS.FF),根据这一行可以知道该sql耗时在了哪个地方。
Buffers为每一步实际执行的逻辑读或一致性读。
Reads为物理读。
OMem、1Mem为执行所需的内存评估值,0Mem为最优执行模式所需内存的评估值,1Mem为one-pass模式所需内存的评估值。
0/1/M 为最优/one-pass/multipass执行的次数。
Used-Mem耗的内存

------------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------
|   1 |  SORT AGGREGATE     |       |      1 |      1 |      1 |00:00:00.01 |      19 |       |       |          |
|*  2 |   HASH JOIN         |       |      1 |    100 |    100 |00:00:00.01 |      19 |  1066K|  1066K| 1162K (0)|
|   3 |    TABLE ACCESS FULL| TEST1 |       |   1000 |   1000 |00:00:00.01 |      15 |       |       |          |
------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")

SQL> select /*+leading(t1) use_hash (t2)*/count(*)
      from test1 t1, test2 t2
     where t1.object_id = t2.object_id
       and t1.object_id = 99999;
  COUNT(*)
----------
         0

SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  f9zwsrs05kg0n, child number 0
-------------------------------------
select /*+leading(t1) use_hash (t2)*/count(*)   from test1 t1, test2 t2  where t1.object_id =
t2.object_id    and t1.object_id = 99999
Plan hash value: 2544416891
------------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------
|   1 |  SORT AGGREGATE     |       |      1 |      1 |      1 |00:00:00.01 |       4 |       |       |          |
|*  2 |   HASH JOIN         |       |      1 |      1 |      0 |00:00:00.01 |       4 |   921K|   921K|  176K (0)|
|*  3 |    TABLE ACCESS FULL| TEST1 |       |      1 |      0 |00:00:00.01 |       4 |       |       |          |
|*  4 |    TABLE ACCESS FULL| TEST2 |       |      1 |      0 |00:00:00.01 |       0 |       |       |          |
------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
   3 - filter("T1"."OBJECT_ID"=99999)
   4 - filter("T2"."OBJECT_ID"=99999)

SQL> select /*+leading(t1) use_hash (t2)*/count(*)
  2    from test1 t1, test2 t2
  3   where t1.object_id = t2.object_id
  4     and 1=2;
  COUNT(*)
----------
         0
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  bnrfbt4ybxnnp, child number 0
-------------------------------------
select /*+leading(t1) use_hash (t2)*/count(*)   from test1 t1, test2 t2  where t1.object_id =
t2.object_id    and 1=2
Plan hash value: 1013001923
---------------------------------------------------------------------------------------------------------
| Id  | Operation            | Name  | Starts | E-Rows | A-Rows |   A-Time   |  OMem |  1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------
|   1 |  SORT AGGREGATE      |       |      1 |      1 |      1 |00:00:00.01 |       |       |       |
|*  2 |   FILTER             |       |      1 |        |      0 |00:00:00.01 |       |       |       |
|*  3 |    HASH JOIN         |       |      0 |    100 |      0 |00:00:00.01 |   921K|   921K|       |
|   4 |     TABLE ACCESS FULL| TEST1 |       |    100 |      0 |00:00:00.01 |       |       |       |
|   5 |     TABLE ACCESS FULL| TEST2 |       |   1000 |      0 |00:00:00.01 |       |       |       |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(NULL IS NOT NULL)
   3 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")

哈希连接(hash join) 原理的更多相关文章

  1. oracle 表连接 - hash join 哈希连接

    一. hash 连接(哈希连接)原理 指的是两个表连接时, 先利用两表中记录较少的表在内存中建立 hash 表, 然后扫描记录较多的表并探測 hash 表, 找出与 hash 表相匹配的行来得到结果集 ...

  2. oracle多表连接方式Hash Join Nested Loop Join Merge Join

    在查看sql执行计划时,我们会发现表的连接方式有多种,本文对表的连接方式进行介绍以便更好看懂执行计划和理解sql执行原理. 一.连接方式:        嵌套循环(Nested  Loops (NL) ...

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

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

  4. HASH JOIN算法

    哈希连接(HASH JOIN) 前文提到,嵌套循环只适合输出少量结果集.如果要返回大量结果集(比如返回100W数据),根据嵌套循环算法,被驱动表会扫描100W次,显然这是不对的.看到这里你应该明白为 ...

  5. Oracle 哈希连接原理

    <基于Oracle的sql优化>里关于哈希连接的原理介绍如下: 哈希连接(HASH JOIN)是一种两个表在做表连接时主要依靠哈希运算来得到连接结果集的表连接方法. 在Oracle 7.3 ...

  6. 数据库 Hash Join的定义,原理,算法,成本,模式和位图

    Hash Join只能用于相等连接,且只能在CBO优化器模式下.相对于nested loop join,hash join更适合处理大型结果集       Hash Join的执行计划第1个是hash ...

  7. 多表连接的三种方式详解 hash join、merge join、 nested loop

    在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式.多表之间的连接有三种方式:Nested Loops,Hash Join 和 Sort Merge Join.具体适用哪 ...

  8. 浅谈SQL Server中的三种物理连接操作(HASH JOIN MERGE JOIN NESTED LOOP)

    简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...

  9. Merge join、Hash join、Nested loop join对比分析

    简介 我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge Join,Hash Join ...

随机推荐

  1. go 第一个项目

    官方下载go: https://golang.org/dl/ 安装完成后:cmd命令下:go go env:查看当前的环境配置:

  2. Eletron 打开文件夹,截图

    1.shell.openItem(fullPath) var fullpath = path.join(processPath)+Math.random()+".png"; she ...

  3. java基础六 [异常处理](阅读Head First Java记录)

    在程序运行时,我们不能保证所有服务和方法都是正确的,如果发生问题报错会导致程序崩溃,所以需要对一些可以预见的错误进行异常处理,通过throw去抛出一个异常,然后用try..catch..将要执行的该方 ...

  4. IE6、IE7、Firefox中margin问题及input解决办法

    margin不居中的问题 .div{ margin:10px;/*ff*/ *margin:15px;/*ie7*/ _margin:15px;/*ie6*/  尺寸会变为正常的两倍,按道理应为5px ...

  5. count++线程安全与 synchronized对性能影响的测试

    一个计时器,同时开启100个线程,每个线程休眠1ms钟后,将全局静态变量count加1,这100个线程创建完之后,休眠500ms,计算总耗时,程序如下: public class Counter { ...

  6. Visual Studio 2008 简体中文正式版下载及序列号(无使用期限限制,正式版)

    VS2008中文试用版刚出来不久就上网拖了下来可是安装的时候却出问题了.后来,Google了下,把自己遇到的问题和解决方法跟大家分享.1.让试用版变成正式版    从Microsoft那下了7个压缩文 ...

  7. Intersecting Lines(叉积,方程)

    Intersecting Lines http://poj.org/problem?id=1269 Time Limit: 1000MS   Memory Limit: 10000K Total Su ...

  8. EXP-00056:遇到oracle错误12154

    执行命令如下: 引用 exp user/pwd@dbname file=d:text.dmp owner=(user) 碰到了错误: 引用 EXP-00056:遇到oracle错误12154 ORA- ...

  9. 如何区分USB 2.0 和USB 3.0插口

    USB3.0的速度是USB2.0的十倍,并且比USB2.0更加节能,同时,还能向下兼容USB2.0.那么,我们怎么区分USB2.0 和 USB 3.0呢. 电脑(有USB2.0和USB3.0的插口) ...

  10. 基于udp的套接字

    1 ss = socket() #创建一个服务器的套接字 2 ss.bind() #绑定服务器套接字 3 inf_loop: #服务器无限循环 4 cs = ss.recvfrom()/ss.send ...