zoukankan      html  css  js  c++  java
  • oracle-常见的执行计划(一)

    一、表访问方式

    CBO基础概念中有讲到,访问表的方式有两种:全表扫描和ROWID扫描。

    全表扫描的执行计划:TABLE ACCESS FULL

    ROWID扫描对应执行计划:TABLE ACCESS BY USER ROWID 或 TABLE ACCESS BY INDEX ROWID

    通过例子说明

    (一)、全表扫描方式

    select empno,ename from scott.emp
          
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  6c0fp61y99tuw, child number 0
    -------------------------------------
    select empno,ename from scott.emp
     
    Plan hash value: 3956160932
     
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |       |       |     3 (100)|          |
    |   1 |  TABLE ACCESS FULL| EMP  |    14 |   140 |     3   (0)| 00:00:01 |
    --------------------------------------------------------------------------
     

    (二)、rowid访问方式

    1、TABLE ACCESS BY USER ROWID

    select empno,ename from scott.emp where rowid='AAASZHAAEAAAACXAAA'
      
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  99f9cvxt33nzy, child number 0
    -------------------------------------
    select empno,ename from scott.emp where rowid='AAASZHAAEAAAACXAAA'
     
    Plan hash value: 1116584662
     
    -----------------------------------------------------------------------------------
    | Id  | Operation                  | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT           |      |       |       |     1 (100)|          |
    |   1 |  TABLE ACCESS BY USER ROWID| EMP  |     1 |    22 |     1   (0)| 00:00:01 |
    -----------------------------------------------------------------------------------
    

    2、TABLE ACCESS BY INDEX ROWID

    select empno,ename from scott.emp where empno=7521
      
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  69nxfycyppq7m, child number 0
    -------------------------------------
    select empno,ename from scott.emp where empno=7521
     
    Plan hash value: 2949544139
     
    --------------------------------------------------------------------------------------
    | Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |        |       |       |     1 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    10 |     1   (0)| 00:00:01 |
    |*  2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)|          |
    --------------------------------------------------------------------------------------
    ...
     

    二、B*树访问方式

    索引唯一扫描、索引范围扫描、索引全扫描、索引快速扫描、索引跳跃式扫描

    以上这些执行计划执行计划相对应

    • 索引唯一扫描:INDEX UNIQUE SCAN
    • 索引范围扫描:INDEX RANGE SCAN
    • 索引全扫描:INDEX FULL SCAN
    • 索引快速全扫描:INDEX FAST FULL SCAN
    • 索引跳跃式扫描:INDEX SKIP SCAN

    例子说明

    (一)、索引唯一扫描:INDEX UNIQUE SCAN

    select empno,ename from scott.emp where empno=7521
      
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  69nxfycyppq7m, child number 0
    -------------------------------------
    select empno,ename from scott.emp where empno=7521
     
    Plan hash value: 2949544139
     
    --------------------------------------------------------------------------------------
    | Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |        |       |       |     1 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    10 |     1   (0)| 00:00:01 |
    |*  2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)|          |
    --------------------------------------------------------------------------------------
     
    

    通过唯一索引的方式获取rowid访问表中的以rowid的方式

    (二)、索引范围扫描:INDEX RANGE SCAN

    select empno,ename from scott.emp where empno>=7521 and empno<=8521
      
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  95m0uw0yxc10w, child number 0
    -------------------------------------
    select empno,ename from scott.emp where empno>=7521 and empno<=8521
     
    Plan hash value: 169057108
     
    --------------------------------------------------------------------------------------
    | Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |        |       |       |     2 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |    11 |   110 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | PK_EMP |    11 |       |     1   (0)| 00:00:01 |
    --------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       2 - access("EMPNO">=7521 AND "EMPNO"<=8521)
     

    谓词中存在大于、小于的访问方式时,并且这个谓词建议过索引,基本采用索引范围扫描的方式

    (三)、索引全扫描:INDEX FULL SCAN

    select empno,ename from scott.emp order by empno
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  3bt7b5h1rxh6z, child number 0
    -------------------------------------
    select empno,ename from scott.emp order by empno
     
    Plan hash value: 4170700152
     
    --------------------------------------------------------------------------------------
    | Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |        |       |       |     2 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |    14 |   140 |     2   (0)| 00:00:01 |
    |   2 |   INDEX FULL SCAN           | PK_EMP |    14 |       |     1   (0)| 00:00:01 |
    --------------------------------------------------------------------------------------
     

    当索引列的定义可以为null

    create index ind_EMP_JOB  ON scott.emp(JOB); 
             
    select empno,ename from scott.emp order by job
          
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  cnpptzn6mshrb, child number 0
    -------------------------------------
    select empno,ename from scott.emp order by job
     
    Plan hash value: 150391907
     
    ---------------------------------------------------------------------------
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |       |       |     4 (100)|          |
    |   1 |  SORT ORDER BY     |      |    14 |   252 |     4  (25)| 00:00:01 |
    |   2 |   TABLE ACCESS FULL| EMP  |    14 |   252 |     3   (0)| 00:00:01 |
    ---------------------------------------------------------------------------
     

    发现如果JOB列定义可以为空的话,order by 是不会走索引的。

    调整列的属性,不能为空,在查看执行计划

    alter table scott.emp modify(job not null)
              
    select empno,ename from scott.emp order by job
          
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  cnpptzn6mshrb, child number 0
    -------------------------------------
    select empno,ename from scott.emp order by job
     
    Plan hash value: 157317628
     
    -------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |             |       |       |     2 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID| EMP         |    14 |   252 |     2   (0)| 00:00:01 |
    |   2 |   INDEX FULL SCAN           | IND_EMP_JOB |    14 |       |     1   (0)| 00:00:01 |
    -------------------------------------------------------------------------------------------
     

    (四)、索引快速全扫描:INDEX FAST FULL SCAN

    select /*+index_ffs(a ind_EMP_JOB)*/ job  from scott.emp a
          
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  3hu16hz75qkhu, child number 0
    -------------------------------------
    select /*+index_ffs(a ind_EMP_JOB)*/ job  from scott.emp a
     
    Plan hash value: 2520590889
     
    ------------------------------------------------------------------------------------
    | Id  | Operation            | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT     |             |       |       |     2 (100)|          |
    |   1 |  INDEX FAST FULL SCAN| IND_EMP_JOB |    14 |   112 |     2   (0)| 00:00:01 |
    ------------------------------------------------------------------------------------
     

    这里使用HINT,强制提示优化器走fast索引的方式

    (五)、索引跳跃式扫描:INDEX SKIP SCAN

    用于复合索引中的,非索引前导列的访问

    create index ind_EMP_JENAME  ON scott.emp(JOB,ename); 
              
    select empno,ename from scott.emp where ename='ALLEN'
    
    SQL_ID  bdfu46xwtg0qk, child number 0
    -------------------------------------
    select empno,ename from scott.emp where ename='ALLEN'
     
    Plan hash value: 878294805
     
    ----------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |                |       |       |     2 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID| EMP            |     1 |    10 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX SKIP SCAN           | IND_EMP_JENAME |     1 |       |     1   (0)| 00:00:01 |
    ----------------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       2 - access("ENAME"='ALLEN')
           filter("ENAME"='ALLEN')
     

    三、位图索引访问的方式

    适用于数据仓库,不适用OLTP系统,物理存储结构类似B*数索引,对应rowid的上限、rowid的下限、位图段。

    对于oracle数据库中的位图索引而言,他是没有行锁这个概念的,要锁就锁索引行的整个位图段,而多个数据行可能对应同一个索引行的位图段,这个锁的粒度就决定了位图索引不适用于高并发并频繁修改的OLTP系统,在OLTP系统中,很容易产生死锁。

    • 位图索引单键值扫描:BITMAP INDEX SINGLE VALUE
    • 位图索引范围扫描: BITMAP INDEX RANGE SCAN
    • 位图索引全扫描: BITMAP INDEX FULL SCAN
    • 位图索引快速全扫描: BITMAP INDEX FAST FULL SCAN
    • 位图按位与: BITMAP  AND
    • 位图按位或: BITMAP OR
    • 位图按位减: BITMAP MINUS

    (一)、构造一张表,测试位图索引

    Create table test_normal (empno number(10), ename varchar2(30), sal number(10)) TABLESPACE GLL01;
    
    Begin
    For i in 1..1000000
    Loop
       Insert into test_normal 
       values(i, dbms_random.string('U',30), dbms_random.value(1000,7000));
       If mod(i, 10000) = 0 then
       Commit;
      End if;
    End loop;
    End;
    
    create bitmap index normal_empno_bmx on test_normal(empno) TABLESPACE GLL01;
    
    create bitmap index normal_empno_sal on test_normal(sal) TABLESPACE GLL01;
    
    EXECUTE DBMS_STATS.GATHER_TABLE_STATS('SYS','TEST_NORMAL',CASCADE=>TRUE);
     

    (二)、位图索引单键值扫描:BITMAP INDEX SINGLE VALUE

    select * from test_normal where empno=1000
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  343wc0yvq4cc9, child number 0
    -------------------------------------
    select * from test_normal where empno=1000
     
    Plan hash value: 4267925254
     
    -------------------------------------------------------------------------------------------------
    | Id  | Operation                    | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT             |                  |       |       |     3 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID | TEST_NORMAL      |     1 |    40 |     3   (0)| 00:00:01 |
    |   2 |   BITMAP CONVERSION TO ROWIDS|                  |       |       |            |          |
    |*  3 |    BITMAP INDEX SINGLE VALUE | NORMAL_EMPNO_BMX |       |       |            |          |
    -------------------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       3 - access("EMPNO"=1000)
     

    (三)、位图索引范围扫描: BITMAP INDEX RANGE SCAN

    select * from  test_normal where empno>=50 and  empno<=2000
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  34p69q6q4wqxx, child number 0
    -------------------------------------
    select * from  test_normal where empno>=50 and  empno<=2000
     
    Plan hash value: 641040856
     
    -------------------------------------------------------------------------------------------------
    | Id  | Operation                    | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT             |                  |       |       |   362 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID | TEST_NORMAL      |  1952 | 78080 |   362   (0)| 00:00:05 |
    |   2 |   BITMAP CONVERSION TO ROWIDS|                  |       |       |            |          |
    |*  3 |    BITMAP INDEX RANGE SCAN   | NORMAL_EMPNO_BMX |       |       |            |          |
    -------------------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       3 - access("EMPNO">=50 AND "EMPNO"<=2000)
     

    (四)、位图索引全扫描: BITMAP INDEX FULL SCAN

    select /*+index(a normal_empno_bmx)*/  a.empno  from  test_normal a
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  cmxdf5ry1gvw1, child number 0
    -------------------------------------
    select /*+index(a normal_empno_bmx)*/  a.empno  from  test_normal a
     
    Plan hash value: 220257735
     
    ------------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |                  |       |       |  3496 (100)|          |
    |   1 |  BITMAP CONVERSION TO ROWIDS|                  |  1000K|  4882K|  3496   (1)| 00:00:42 |
    |   2 |   BITMAP INDEX FULL SCAN    | NORMAL_EMPNO_BMX |       |       |            |          |
    ------------------------------------------------------------------------------------------------
     

    (五)、位图索引快速全扫描: BITMAP INDEX FAST FULL SCAN

    select /*+index_ffs(a normal_empno_bmx)*/  a.empno  from  test_normal a
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  9rgzkasky186v, child number 0
    -------------------------------------
    select /*+index_ffs(a normal_empno_bmx)*/  a.empno  from  test_normal a
     
    Plan hash value: 2075344169
     
    -------------------------------------------------------------------------------------------------
    | Id  | Operation                    | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT             |                  |       |       |  3141 (100)|          |
    |   1 |  BITMAP CONVERSION TO ROWIDS |                  |  1000K|  4882K|  3141   (1)| 00:00:38 |
    |   2 |   BITMAP INDEX FAST FULL SCAN| NORMAL_EMPNO_BMX |       |       |            |          |
    -------------------------------------------------------------------------------------------------
     

    (六)、位图按位与: BITMAP AND、BITMAP OR

    select * from  test_normal where empno=3969  and  sal in (1008,1011)
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  cyf5th2ts2z7j, child number 0
    -------------------------------------
    select * from  test_normal where empno=3969  and  sal in (1008,1011)
     
    Plan hash value: 640003492
     
    --------------------------------------------------------------------------------------------------
    | Id  | Operation                     | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT              |                  |       |       |     5 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID  | TEST_NORMAL      |     1 |    40 |     5   (0)| 00:00:01 |
    |   2 |   BITMAP CONVERSION TO ROWIDS |                  |       |       |            |          |
    |   3 |    BITMAP AND                 |                  |       |       |            |          |
    |   4 |     BITMAP OR                 |                  |       |       |            |          |
    |*  5 |      BITMAP INDEX SINGLE VALUE| NORMAL_EMPNO_SAL |       |       |            |          |
    |*  6 |      BITMAP INDEX SINGLE VALUE| NORMAL_EMPNO_SAL |       |       |            |          |
    |*  7 |     BITMAP INDEX SINGLE VALUE | NORMAL_EMPNO_BMX |       |       |            |          |
    --------------------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       5 - access("SAL"=1008)
       6 - access("SAL"=1011)
       7 - access("EMPNO"=3969)
     

    (七)、位图按位减: BITMAP MINUS

    select /*+index_ffs(test_normal normal_empno_sal)*/  * from  test_normal where empno>=50 and  empno<=20000 and  sal not in (1008)
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  dn3yq5vrp1524, child number 0
    -------------------------------------
    select /*+index_ffs(test_normal normal_empno_sal)*/  * from  
    test_normal where empno>=50 and  empno<=20000 and  sal not in (1008)
     
    Plan hash value: 3977516083
     
    --------------------------------------------------------------------------------------------------
    | Id  | Operation                     | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT              |                  |       |       |  1385 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID  | TEST_NORMAL      | 19949 |   779K|  1385   (1)| 00:00:17 |
    |   2 |   BITMAP CONVERSION TO ROWIDS |                  |       |       |            |          |
    |   3 |    BITMAP MINUS               |                  |       |       |            |          |
    |   4 |     BITMAP MINUS              |                  |       |       |            |          |
    |   5 |      BITMAP MERGE             |                  |       |       |            |          |
    |*  6 |       BITMAP INDEX RANGE SCAN | NORMAL_EMPNO_BMX |       |       |            |          |
    |*  7 |      BITMAP INDEX SINGLE VALUE| NORMAL_EMPNO_SAL |       |       |            |          |
    |*  8 |     BITMAP INDEX SINGLE VALUE | NORMAL_EMPNO_SAL |       |       |            |          |
    --------------------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       6 - access("EMPNO">=50 AND "EMPNO"<=20000)
       7 - access("SAL"=1008)
       8 - access("SAL" IS NULL)
     

    列值为NULL,位图索引是记录,以上这个例子中也把列为NULL剔除


    四、表连接的访问方式

    • 嵌套循环连接:NESTED LOOPS
    • 哈希连接:hash join
    • 排序合并连接:sort join和merge join
    • 反连接:nested loops anti、hash join anti、merge join anti
    • 半连接:nested loop semi、hash join semi、merge join semi

    (一)、嵌套循环连接:NESTED LOOPS

    select /*+leading(a) use_nl(b)*/* from scott.emp a , scott.dept b  where a.deptno=b.deptno
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  c6xax626nhn8k, child number 0
    -------------------------------------
    select /*+leading(a) use_nl(b)*/* from scott.emp a , scott.dept b  
    where a.deptno=b.deptno
     
    Plan hash value: 3625962092
     
    ----------------------------------------------------------------------------------------
    | Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT             |         |       |       |    17 (100)|          |
    |   1 |  NESTED LOOPS                |         |       |       |            |          |
    |   2 |   NESTED LOOPS               |         |    14 |   798 |    17   (0)| 00:00:01 |
    |   3 |    TABLE ACCESS FULL         | EMP     |    14 |   532 |     3   (0)| 00:00:01 |
    |*  4 |    INDEX UNIQUE SCAN         | PK_DEPT |     1 |       |     0   (0)|          |
    |   5 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    19 |     1   (0)| 00:00:01 |
    ----------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       4 - access("A"."DEPTNO"="B"."DEPTNO")
     

    (二)、哈希连接:hash join

    select /*+leading(a) use_hash(b)*/* from scott.emp a , scott.dept b  where a.deptno=b.deptno
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  fq65sryy1d9dw, child number 0
    -------------------------------------
    select /*+leading(a) use_hash(b)*/* from scott.emp a , scott.dept b  
    where a.deptno=b.deptno
     
    Plan hash value: 1123238657
     
    ---------------------------------------------------------------------------
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |       |       |     7 (100)|          |
    |*  1 |  HASH JOIN         |      |    14 |   798 |     7  (15)| 00:00:01 |
    |   2 |   TABLE ACCESS FULL| EMP  |    14 |   532 |     3   (0)| 00:00:01 |
    |   3 |   TABLE ACCESS FULL| DEPT |     3 |    57 |     3   (0)| 00:00:01 |
    ---------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       1 - access("A"."DEPTNO"="B"."DEPTNO")
     

    (三)、排序合并连接:sort join和merge join

    select /*+use_merge(a b)*/* from scott.emp a , scott.dept b  where a.deptno=b.deptno
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  9w06suya2pdrn, child number 0
    -------------------------------------
    select /*+use_merge(a b)*/* from scott.emp a , scott.dept b  where 
    a.deptno=b.deptno
     
    Plan hash value: 844388907
     
    ----------------------------------------------------------------------------------------
    | Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT             |         |       |       |     6 (100)|          |
    |   1 |  MERGE JOIN                  |         |    14 |   798 |     6  (17)| 00:00:01 |
    |   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     3 |    57 |     2   (0)| 00:00:01 |
    |   3 |    INDEX FULL SCAN           | PK_DEPT |     3 |       |     1   (0)| 00:00:01 |
    |*  4 |   SORT JOIN                  |         |    14 |   532 |     4  (25)| 00:00:01 |
    |   5 |    TABLE ACCESS FULL         | EMP     |    14 |   532 |     3   (0)| 00:00:01 |
    ----------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       4 - access("A"."DEPTNO"="B"."DEPTNO")
           filter("A"."DEPTNO"="B"."DEPTNO")
     

    (四)、反连接:nested loops anti

    alter table scott.emp modify(deptno not  null)
    
    select * from scott.emp  a WHERE A.DEPTNO NOT   IN (SELECT  /*+nl_aj*/  DEPTNO FROM scott.dept b where a.deptno=b.deptno)
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  dh1c9mwpw9pjx, child number 0
    -------------------------------------
    select * from scott.emp  a WHERE A.DEPTNO NOT   IN (SELECT  /*+nl_aj*/  
    DEPTNO FROM scott.dept b where a.deptno=b.deptno)
     
    Plan hash value: 3496123964
     
    ------------------------------------------------------------------------------
    | Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |         |       |       |     3 (100)|          |
    |   1 |  NESTED LOOPS ANTI |         |     7 |   287 |     3   (0)| 00:00:01 |
    |   2 |   TABLE ACCESS FULL| EMP     |    14 |   532 |     3   (0)| 00:00:01 |
    |*  3 |   INDEX UNIQUE SCAN| PK_DEPT |     2 |     6 |     0   (0)|          |
    ------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       3 - access("A"."DEPTNO"="B"."DEPTNO")
     

    (五)、反连接:hash join anti

    select * from scott.emp a WHERE A.DEPTNO NOT  IN (SELECT /*+hash_aj*/    DEPTNO FROM scott.dept b where a.deptno=b.deptno)
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  dhq4hhqgqqn0n, child number 0
    -------------------------------------
    select * from scott.emp a WHERE A.DEPTNO NOT  IN (SELECT /*+hash_aj*/   
     DEPTNO FROM scott.dept b where a.deptno=b.deptno)
     
    Plan hash value: 1958379418
     
    ------------------------------------------------------------------------------
    | Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |         |       |       |     5 (100)|          |
    |*  1 |  HASH JOIN ANTI    |         |     7 |   287 |     5  (20)| 00:00:01 |
    |   2 |   TABLE ACCESS FULL| EMP     |    14 |   532 |     3   (0)| 00:00:01 |
    |   3 |   INDEX FULL SCAN  | PK_DEPT |     3 |     9 |     1   (0)| 00:00:01 |
    ------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       1 - access("A"."DEPTNO"="B"."DEPTNO")
     

    (六)、反连接:merge join anti

    select * from scott.emp  a WHERE A.DEPTNO NOT   IN (SELECT  /*+merge_aj*/  DEPTNO FROM scott.dept b where a.deptno=b.deptno)
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  1r60ktudp9vq2, child number 0
    -------------------------------------
    select * from scott.emp  a WHERE A.DEPTNO NOT   IN (SELECT  
    /*+merge_aj*/  DEPTNO FROM scott.dept b where a.deptno=b.deptno)
     
    Plan hash value: 4267419248
     
    -------------------------------------------------------------------------------
    | Id  | Operation           | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |         |       |       |     6 (100)|          |
    |   1 |  MERGE JOIN ANTI    |         |     7 |   287 |     6  (34)| 00:00:01 |
    |   2 |   SORT JOIN         |         |    14 |   532 |     4  (25)| 00:00:01 |
    |   3 |    TABLE ACCESS FULL| EMP     |    14 |   532 |     3   (0)| 00:00:01 |
    |*  4 |   SORT UNIQUE       |         |     3 |     9 |     2  (50)| 00:00:01 |
    |   5 |    INDEX FULL SCAN  | PK_DEPT |     3 |     9 |     1   (0)| 00:00:01 |
    -------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       4 - access("A"."DEPTNO"="B"."DEPTNO")
           filter("A"."DEPTNO"="B"."DEPTNO")
     

    (七)、半连接:nested loop semi

    select * from scott.emp a WHERE  EXISTS (SELECT /*+nl_sj*/  1 FROM scott.dept b where a.deptno=b.deptno)
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  9htytj0pxjhkg, child number 0
    -------------------------------------
    select * from scott.emp a WHERE  EXISTS (SELECT /*+nl_sj*/  1 FROM 
    scott.dept b where a.deptno=b.deptno)
     
    Plan hash value: 3274513678
     
    ------------------------------------------------------------------------------
    | Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |         |       |       |     3 (100)|          |
    |   1 |  NESTED LOOPS SEMI |         |     7 |   287 |     3   (0)| 00:00:01 |
    |   2 |   TABLE ACCESS FULL| EMP     |    14 |   532 |     3   (0)| 00:00:01 |
    |*  3 |   INDEX UNIQUE SCAN| PK_DEPT |     2 |     6 |     0   (0)|          |
    ------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       3 - access("A"."DEPTNO"="B"."DEPTNO")
     

    (八)、半连接:hash join semi

    select * from scott.emp a WHERE  EXISTS (SELECT /*+hash_sj*/  1 FROM scott.dept b where a.deptno=b.deptno)
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  cjhjgkgs8q1fc, child number 0
    -------------------------------------
    select * from scott.emp a WHERE  EXISTS (SELECT /*+hash_sj*/  1 FROM 
    scott.dept b where a.deptno=b.deptno)
     
    Plan hash value: 3753861400
     
    ------------------------------------------------------------------------------
    | Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |         |       |       |     5 (100)|          |
    |*  1 |  HASH JOIN SEMI    |         |     7 |   287 |     5  (20)| 00:00:01 |
    |   2 |   TABLE ACCESS FULL| EMP     |    14 |   532 |     3   (0)| 00:00:01 |
    |   3 |   INDEX FULL SCAN  | PK_DEPT |     3 |     9 |     1   (0)| 00:00:01 |
    ------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       1 - access("A"."DEPTNO"="B"."DEPTNO")
     

    (九)、半连接:merge join semi

    select * from scott.emp a WHERE  EXISTS (SELECT /*+merge_sj*/  1 FROM scott.dept b where a.deptno=b.deptno)
    
    select *from table(dbms_xplan.display_cursor(null,null))
    
    SQL_ID  f2zxcjpqvpsu5, child number 0
    -------------------------------------
    select * from scott.emp a WHERE  EXISTS (SELECT /*+merge_sj*/  1 FROM 
    scott.dept b where a.deptno=b.deptno)
     
    Plan hash value: 3011744318
     
    -------------------------------------------------------------------------------
    | Id  | Operation           | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |         |       |       |     6 (100)|          |
    |   1 |  MERGE JOIN SEMI    |         |     7 |   287 |     6  (34)| 00:00:01 |
    |   2 |   SORT JOIN         |         |    14 |   532 |     4  (25)| 00:00:01 |
    |   3 |    TABLE ACCESS FULL| EMP     |    14 |   532 |     3   (0)| 00:00:01 |
    |*  4 |   SORT UNIQUE       |         |     3 |     9 |     2  (50)| 00:00:01 |
    |   5 |    INDEX FULL SCAN  | PK_DEPT |     3 |     9 |     1   (0)| 00:00:01 |
    -------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       4 - access("A"."DEPTNO"="B"."DEPTNO")
           filter("A"."DEPTNO"="B"."DEPTNO")
     
  • 相关阅读:
    zTree学习笔记之展开树和收起树
    添优--史上超级全面的前端面试题大集合
    springboot2.0整合jpa
    Idea快捷键
    实用工具收藏
    nginx
    SQLServer锁的机制
    centos安装jenkins
    java8
    前端开发收藏
  • 原文地址:https://www.cnblogs.com/gull/p/5574548.html
Copyright © 2011-2022 走看看