哈希连接(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. tensorflow学习资料

    tensorflow学习资料 http://www.soku.com/search_video/q_tensorflow?f=1&kb=04112020yv41000__&_rp=1a ...

  2. ==、is

    ==.is 总结 is 是比较两个引用是否指向了同一个对象(引用比较). == 是比较两个对象的值是否相等(值比较).

  3. yum 操作

    一.使用yum安装和卸载软件,有个前提是yum安装的软件包都是rpm格式的. 安装的命令是,yum install ~,yum会查询数据库,有无这一软件包,如果有,则检查其依赖冲突关系,如果没有依赖冲 ...

  4. Maven 基础配置

    pom.xml基础配置: maven中,最让我迷惑的还是那一堆配置! 就拿这个属性配置来说: <properties> <project.build.sourceEncoding&g ...

  5. Swagger+ springfox +Spring mvc

    简介 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集 ...

  6. Java的反射和代理以及注解

    最近接触到java的反射和代理(接触的有点迟了...),还是有必要总结下 1. Java的反射 有的时候我们需要在程序运行的时候获取类.方法等信息用于动态运行,这个时候反射就能够帮我们找到类.方法.成 ...

  7. Redis事务的简单理解

    Redis事务的命令如下所示: 先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令 示例如下: //开始一个事务 > MU ...

  8. 使用HttpModule实现网址重写

    1.  修改配置文件: <httpModules> <</span>add name="html" type="HttpModule&quo ...

  9. apache配置防盗链

    1.确保apache已开启rewrite.   2.在.htaccess文件中添加如下: RewriteEngine On RewriteCond %{HTTP_REFERER} !^http://X ...

  10. springmvc中Controller方法的返回值

    1.1 返回ModelAndView controller方法中定义ModelAndView对象并返回,对象中可添加model数据.指定view. 1.2 返回void 在controller方法形参 ...