哈希连接(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. git基本命令之删除撤销操作

    1.将删除文件恢复--撤销所删除的文件git checkout 文件名 2.git resetgit reset --hard commitID(或某个节点)----强制切换到某个点,会导致所修改的内 ...

  2. go递归函数如何传递数组切片slice

    数组切片slice这个东西看起来很美好,真正用起来会发现有诸多的不爽. 第一,数组.数组切片混淆不清,使用方式完全一样,有时候一些特性又完全不一样,搞不清原理很容易误使用. 第二,数组切片的appen ...

  3. TensorFlow RNN MNIST字符识别演示快速了解TF RNN核心框架

    TensorFlow RNN MNIST字符识别演示快速了解TF RNN核心框架 http://blog.sina.com.cn/s/blog_4b0020f30102wv4l.html

  4. docker 配置远程访问证书验证

    centos7 生成证书 工具:openssl #cd /etc/docker   (docker的证书一般放这) #openssl genrsa -aes256 -passout pass:密码   ...

  5. R包和python对应的库

    数据库 类别 Python R MySQL mysql-connector-python(官方) RMySQL Oracle cx_Oracle ROracle Redis redis rredis ...

  6. Enterprise Library 企业库

    微软企业库,提供了一套日志,缓存等功能的库.可以通过NuGet安装.

  7. Poor Warehouse Keeper

    Poor Warehouse Keeper http://acm.hdu.edu.cn/showproblem.php?pid=4803 Jenny is a warehouse keeper. He ...

  8. ArrayList LinkList比较

    1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构.      2.对于随机访问get和set,ArrayList优于LinkedList,因为ArrayLi ...

  9. 基于AspectJ的XML方式进行AOP开发

    -------------------siwuxie095                                 基于 AspectJ 的 XML 方式进行 AOP 开发         1 ...

  10. access数据库收缩(压缩)

    一般是因为表中有大量没用的数据,把没用的数据全部删除 菜单栏的“工具”——“数据库实用工具”——“压缩和修复数据库” OK啦