• hash join 只支持等值连接


    alter session set statistics_level=all; 
    
    select /*+ use_hash(emp,dept) */ ename,job,sal ,dname,loc from emp,dept where emp.deptno=dept.deptno;
    
    
    
    SQL> select /*+ use_hash(emp,dept) */ ename,job,sal ,dname,loc from emp,dept where emp.deptno=dept.deptno;
    
    ENAME			       JOB				  SAL DNAME					 LOC
    ------------------------------ --------------------------- ---------- ------------------------------------------ ---------------------------------------
    SMITH			       CLERK				  800 RESEARCH					 DALLAS
    ALLEN			       SALESMAN 			 1600 SALES					 CHICAGO
    WARD			       SALESMAN 			 1250 SALES					 CHICAGO
    JONES			       MANAGER				 2975 RESEARCH					 DALLAS
    MARTIN			       SALESMAN 			 1250 SALES					 CHICAGO
    BLAKE			       MANAGER				 2850 SALES					 CHICAGO
    CLARK			       MANAGER				 2450 ACCOUNTING				 NEW YORK
    SCOTT			       ANALYST				 3000 RESEARCH					 DALLAS
    KING			       PRESIDENT			 5000 ACCOUNTING				 NEW YORK
    TURNER			       SALESMAN 			 1500 SALES					 CHICAGO
    ADAMS			       CLERK				 1100 RESEARCH					 DALLAS
    JAMES			       CLERK				  950 SALES					 CHICAGO
    FORD			       ANALYST				 3000 RESEARCH					 DALLAS
    MILLER			       CLERK				 1300 ACCOUNTING				 NEW YORK
    
    已选择14行。
    
    SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID	gq39gq5cu6jk9, child number 0
    -------------------------------------
    select /*+ use_hash(emp,dept) */ ename,job,sal ,dname,loc from emp,dept
    where emp.deptno=dept.deptno
    
    Plan hash value: 615168685
    
    ----------------------------------------------------------------------------------------------------------------
    | Id  | Operation	   | Name | Starts | E-Rows | A-Rows |	 A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
    ----------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |	  |	 1 |	    |	  14 |00:00:00.01 |	 13 |	    |	    |	       |
    |*  1 |  HASH JOIN	   |	  |	 1 |	 14 |	  14 |00:00:00.01 |	 13 |  1321K|  1321K| 1094K (0)|
    |   2 |   TABLE ACCESS FULL| DEPT |	 1 |	  4 |	   4 |00:00:00.01 |	  6 |	    |	    |	       |
    |   3 |   TABLE ACCESS FULL| EMP  |	 1 |	 14 |	  14 |00:00:00.01 |	  7 |	    |	    |	       |
    ----------------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")
    
    
    已选择21行。
    
    
    DEPT离HASH JOIN关键字最近,表示DEPT是驱动表。 Starts等于1,表示两个表都只扫描了一次。
    
    
    再次强调NESTED LOOPS被驱动表会扫描多次。注意观察Omem,1Mem,Used-Mem,它表示HASH JOIN 会消耗PGA,
    
    当驱动表太大,PGA不能容纳驱动表时,就会产生on-disk HASH JOIN。
    
    现在再回去看看NESTED LOOPS,它没有Omem,1Mem,Used-Mem,也就是说NESTED LOOPS不消耗PGA。
    
    我们再看执行计划中 ID=1 这步,它有*号,前面提到,执行计划中有*表示这个操作有过滤(filter)或者是有access。
    
    
    HASH JOIN属于access。通过谓词过滤信息,我们可以知道HASH JOIN的JOIN列是哪些列在做JOIN。
    
    
    这里就是emp.deptno 和dept.deptno做JOIN。
    
    
    
    select /*+ use_hash(emp,dept) */ ename,job,sal ,dname,loc from emp,dept where emp.deptno<>dept.deptno;
    
    
    SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID	dvf1p4vhyvh37, child number 0
    -------------------------------------
    select /*+ use_hash(emp,dept) */ ename,job,sal ,dname,loc from emp,dept
    where emp.deptno<>dept.deptno
    
    Plan hash value: 4192419542
    
    -------------------------------------------------------------------------------------
    | Id  | Operation	   | Name | Starts | E-Rows | A-Rows |	 A-Time   | Buffers |
    -------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |	  |	 1 |	    |	  42 |00:00:00.01 |	 35 |
    |   1 |  NESTED LOOPS	   |	  |	 1 |	 42 |	  42 |00:00:00.01 |	 35 |
    |   2 |   TABLE ACCESS FULL| DEPT |	 1 |	  4 |	   4 |00:00:00.01 |	  8 |
    |*  3 |   TABLE ACCESS FULL| EMP  |	 4 |	 11 |	  42 |00:00:00.01 |	 27 |
    -------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       3 - filter("EMP"."DEPTNO"<>"DEPT"."DEPTNO")
    
    
    已选择21行。
    
    
  • 相关阅读:
    for是个什么玩意
    面向对象 多态
    面向对象 接口
    面向对象oop
    面向对象基本
    java修饰符的作用范围
    static 关键字介绍
    JsonLayout log4j2 json格式输出日志
    多线程--Thread.join方法
    idea常用实用快捷键
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13348747.html
Copyright © 2020-2023  润新知