oracle-常见的执行计划

Posted gull

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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")
 

以上是关于oracle-常见的执行计划的主要内容,如果未能解决你的问题,请参考以下文章

执行计划-数据访问方式(全表扫描与4种索引的方式)

oracle常见的执行计划

Oracle查看执行计划

oracle 的hint有啥用

Oracle执行计划总结

oracle选择了错误的执行计划,怎么办