日期:2014-05-16  浏览次数:20578 次

如何看懂ORACLE执行计划(转发)
原文:http://blog.csdn.net/java3344520/article/details/5515497

如何看懂ORACLE执行计划
一、什么是执行计划
An explain plan is a representation of the access path that is taken when a query is executed within Oracle.


二、如何访问数据
At the physical level Oracle reads blocks of data. The smallest amount of data read is a single Oracle block, the largest is constrained by operating system limits (and multiblock i/o). Logically Oracle finds the data to read by using the following methods:
Full Table Scan (FTS)    --全表扫描
Index Lookup (unique & non-unique)    --索引扫描(唯一和非唯一)
Rowid    --物理行id


三、执行计划层次关系
When looking at a plan, the rightmost (ie most inndented) uppermost operation is the first thing that is executed. --采用最右最上最先执行的原则看层次关系,在同一级如果某个动作没有子ID就最先执行
1.一个简单的例子:
SQL> select  /*+parallel (e 4)*/  *  from  emp  e;

Execution Plan

----------------------

   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=82 Bytes=7134)

   1    0   TABLE ACCESS* (FULL) OF 'EMP' (Cost=1 Card=82 Bytes=7134):Q5000
--[:Q5000]表示是并行方式
   1 PARALLEL_TO_SERIAL            SELECT /*+ NO_EXPAND ROWID(A1) */ A1."EMPNO"

                                   ,A1."ENAME",A1."JOB",A1."MGR",A1."HI

优化模式是CHOOSE的情况下,看Cost参数是否有值来决定采用CBO还是RBO:
SELECT STATEMENT [CHOOSE] Cost=1234 --Cost有值,采用CBO
SELECT STATEMENT [CHOOSE]           --Cost为空,采用RBO(9I是如此显示的)
2.层次的父子关系的例子:
PARENT1
**FIRST CHILD
****FIRST GRANDCHILD
**SECOND CHILD

Here the same principles apply, the FIRST GRANDCHILD is the initial operation then the FIRST CHILD followed by the SECOND CHILD and finally the PARENT collates the output.


四、例子解说
Execution Plan

----------------------

0 **SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=8 Bytes=248)

1 0 **HASH JOIN (Cost=3 Card=8 Bytes=248)

2 1 ****TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=3 Bytes=36)

3 1 ****TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=16 Bytes=304)
左侧的两排数据,前面的是序列号ID,后面的是对应的PID(父ID)。
A shortened summary of this is:

Execution starts with ID=0: SELECT STATEMENT but this is dependand on it's child objects

So it executes its first child step: ID=1 PID=0 HASH JOIN but this is dependand on it's child objects

So it executes its first child step: ID=2 PID=1 TABLE ACCESS (FULL) OF 'DEPT'

Then the second child step: ID=3 PID=2 TABLE ACCESS (FULL) OF 'EMP'

Rows are returned to the parent step(s) until finished


五、表访问方式
1.Full Table Scan (FTS) 全表扫描
In a FTS operation, the whole table is read up to the high water mark (HWM). The HWM marks the last block in the table that has ever had data written to it. If you have deleted all the rows then you will still read up to the HWM. Truncate resets the HWM back to the start of the table. FTS uses multiblock i/o to read the blocks from disk.   --全表扫描模式下会读数据到表的高水位线(HWM即表示表曾经扩展的最后一个数据块),读取速度依赖于Oracle初始化参数db_block_multiblock_read_count(我觉得应该这样翻译:FTS扫描会使表使用上升到高水位(HWM),HWM标识了表最后写入数据的块,如果你用DELETE删除了所有的数据表仍然处于高水位(HWM),只有用TRUNCATE才能使表回归,FTS使用多IO从磁盘读取数据块).

Query Plan

------------------------------------

SELECT STATEMENT [CHOOSE] Cost=1

**INDEX UNIQUE SCAN EMP_I1   --如果索引里就找到了所要的数据,就不会再去访问表
2.Index Lookup 索引扫描
There are 5 methods of index lookup:
index unique