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")
 
时间: 2024-10-10 07:09:01

oracle-常见的执行计划(一)的相关文章

oracle常见的执行计划

访问表的执行计划: 全表扫描:TABLE ACCESS FULL ROWID扫描:TABLE ACCESS BY USER ROWID (ROWID来源于用户在where条件中的指定)或 TABLE ACCESS BY INDEX ROWID(rowid来源于索引) 与B树索引相关的执行计划: 索引唯一扫描:INDEX UNIQUE SCAN 索引范围扫描:INDEX RANGE SCAN 索引全扫描:INDEX FULL SCAN 索引快速全扫描:INDEX FAST FULL SCAN 索引

oracle里的执行计划-查看

内容主要来自看书学习的笔记,如下记录了常见查询执行计划的方法. 2.2 如何查看执行计划1.explain plan2.dbms_xplan包3.autotrace4.10046事件5.10053事件6.awr/statspack报告(@?/rdbms/admin/awrsqrpt)7.脚本(display_cursor_9i.sql) 2.2.1 explain planexplain plan for sqlselect * from table(dbms_xplan.display);SQ

Oracle rownum影响执行计划

今天调优一条SQL语句,由于SQL比较复杂,用autotrace很难一眼看出哪里出了问题,直接上10046. SELECT AB.* FROM (SELECT A.*, rownum RN FROM (SELECT * from (SELECT DISTINCT (D.DEVICE_ID), F.FUNCTION_LOCATION_ID from GG_device D, GG_CLASSIFY_CARD C, GG_function_location F, GG_fl_device L, GG

查询oracle sql的执行计划时,一个很重要的视图--dba_hist_sql_plan

本文的编写得到枯荣长老的大力帮助,在此表示感谢. 本文适用的oracle db版本为oracle 10g或者更高版本. 之所以说这个视图很重要,是因为该视图中有一列是在awrsqrpt报告中没有的.这一列就是 filter_predicates列. SELECT plan_hash_value, TO_CHAR(RAWTOHEX(child_address)), TO_NUMBER(child_number), id, LPAD(' ', DEPTH) || operation operatio

Oracle查看SQL执行计划的方式

Oracle查看SQL执行计划的方式   获取Oracle sql执行计划并查看执行计划,是掌握和判断数据库性能的基本技巧.下面案例介绍了多种查看sql执行计划的方式: 基本有以下几种方式: 1.通过sql_trace初始化参数 2.通过Autotrace 3.通过explain plan 4.通过dbms_xplan.display_cursor 5.通过dbms_xplan.display_awr 6.通过10046事件 1.通过explain plan 工具 12:24:00 [email

Oracle里的常见的执行计划

与表访问相关的执行计划 Oracle数据库里面与表访问有关的的两种方法:全表扫描和ROWID扫描.反应在执行计划上,与全表扫描对应的执行计划中的关键字是"TABLE ACCESS FULL",与ROWID扫描对应的执行计划中的关键字是"TABLE ACCESS BY USER ROWID"或"TABLE ACCESS BY INDEX ROWID". 我们来看一下与表访问的相关的执行计划,先执行如下SQL: SQL> select empn

转://看懂Oracle中的执行计划

一.什么是Oracle执行计划? 执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述 二.怎样查看Oracle执行计划? 2.1 explain plan for命令查看执行计划 在sql*plus中,执行如下命令: 1)explain plan for select * from XXXX; 2)select * from table(dbms_xplan.display); 2.2 SET AUTOTRACE ON查看执行计划 语法:SET AUTOT[RACE] {OFF |

Oracle数据库查看执行计划

基于ORACLE的应用系统很多性能问题,是由应用系统SQL性能低劣引起的,所以,SQL的性能优化很重要,分析与优化SQL的性能我们一般通过查看该SQL的执行计划,本文就如何看懂执行计划,以及如何通过分析执行计划对SQL进行优化做相应说明. 一.什么是执行计划(explain plan) 执行计划:一条查询语句在ORACLE中的执行过程或访问路径的描述. 二.如何查看执行计划 1: 在PL/SQL下按F5查看执行计划.第三方工具toad等. 很多人以为PL/SQL的执行计划只能看到基数.优化器.耗

最权威Oracle获取SQL执行计划大全

该文档为根据相关资料整理.总结而成,主要讲解Oracle数据库中,获取SQL语句执行计划的最权威.最正确的方法.步骤,此外,还详细说明了每种方法中可选项的意义及使用方法,以方便大家和自己日常工作中查阅使用,因本人未发现本博客支持附件上传功能,需要PDF文件格式的朋友可向我要,也可到群里下载,转载请注明出处. 1.查询v$sql_plan: SQL> col "Query Plan_Table" format a100 SQL> select id,lpad(' ', 2*(

oracle如何查看执行计划

1.在PL/SQL Developer中得到一个SQL的执行计划 输入想要查看执行计划的目标SQL,再按一下快捷键F5就可以了.2.explain plan 命令 explain plan for + 目标SQL select * from table(dbms_xplan.display)3. DBMS_XPLAN 包 1) select * from table(dbms_xplan.display_cursor(null,null,'advanced')) 它用于在SQLPLUS中查看刚刚