ITPub博客

首页 > 数据库 > Oracle > 执行计划的阅读方法

执行计划的阅读方法

原创 Oracle 作者:leon830216 时间:2014-03-01 19:23:31 0 删除 编辑
- 第一个列是步骤的ID
- 第二个列是父步骤的ID
- 第三个列是该步骤要进行的操作
- 在执行过程中,父步骤依赖于子步骤。只有对应的所有子步骤执行完,才能执行父步骤
- 先从最开头一直往右看,直到看到最右边的并列的地方
- 索引扫描(如:INDEX (UNIQUE SCAN))先忽略掉,只考虑剩下的部分
- 对于不并列的,靠右的先执行(2,3)
- 对于并列的,靠上的先执行(2,4)
- 并列的缩进块,从上往下执行(2,4)
- 非并列的缩进块,从下往上执行(2,3)

-- 执行计划部分
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   NESTED LOOPS
   2    1     TABLE ACCESS (BY INDEX ROWID) OF 'TB_HOST_BATCH_DTL'
   3    2       INDEX (RANGE SCAN) OF 'XIE2TB_HOST_BATCH_DTL' (NON-UNIQUE)
   4    1     TABLE ACCESS (BY INDEX ROWID) OF 'TB_BATCH_TRAN_CTRL'
   5    4       INDEX (UNIQUE SCAN) OF 'SYS_C0034652' (UNIQUE)

不妨假设最右边的数据为行号,语句执行是按块进行的
从上述执行计划的开头一直往右看,直到找到最右边并列的,也就是从SELECT STATEMENT开始往右找
找到一级缩进块,只有一个,没有优先级可言,如下
   1    0   NESTED LOOPS
   2    1     TABLE ACCESS (BY INDEX ROWID) OF 'TB_HOST_BATCH_DTL'
   3    2       INDEX (RANGE SCAN) OF 'XIE2TB_HOST_BATCH_DTL' (NON-UNIQUE)
   4    1     TABLE ACCESS (BY INDEX ROWID) OF 'TB_BATCH_TRAN_CTRL'
   5    4       INDEX (UNIQUE SCAN) OF 'SYS_C0034652' (UNIQUE)

再在一级缩进块中找二级缩进块,找到两个,如下
   第一个二级缩进块:
   2    1     TABLE ACCESS (BY INDEX ROWID) OF 'TB_HOST_BATCH_DTL'
   3    2       INDEX (RANGE SCAN) OF 'XIE2TB_HOST_BATCH_DTL' (NON-UNIQUE)
   第二个二级缩进块:
   4    1     TABLE ACCESS (BY INDEX ROWID) OF 'TB_BATCH_TRAN_CTRL'
   5    4       INDEX (UNIQUE SCAN) OF 'SYS_C0034652' (UNIQUE)

按照并列块从上往下执行的原则,第一个二级缩进块的所有语句将优先于第二个二级缩进块的语句执行
而两个二级缩进块执行完,才能执行一级缩进块,这是因为非并列的缩进块,从下往上执行

再在二级缩进块中找三级缩进块
第一个二级缩进块中只有一个三级缩进块,如下:
   3    2       INDEX (RANGE SCAN) OF 'XIE2TB_HOST_BATCH_DTL' (NON-UNIQUE)
由于没有更低层级的缩进块,因此,该块最先执行。然后执行二级缩进块

第二个二级缩进块中也只有一个三级缩进块,如下
   5    4       INDEX (UNIQUE SCAN) OF 'SYS_C0034652' (UNIQUE)
二级缩进块中没有更低层次的缩进块了,因此,执行完第一个二级缩进块的所有语句后,便执行此三级缩进块,再执行对应的二级缩进块。

两个二级缩进块均执行完成后,再执行整个一级缩进块

因此,若按行排序,语句的执行顺序便是: 3 -> 2 -> 5 -> 4 -> 1, 即

   3    2       INDEX (RANGE SCAN) OF 'XIE2TB_HOST_BATCH_DTL' (NON-UNIQUE)
   2    1     TABLE ACCESS (BY INDEX ROWID) OF 'TB_HOST_BATCH_DTL'       
   5    4       INDEX (UNIQUE SCAN) OF 'SYS_C0034652' (UNIQUE)            
   4    1     TABLE ACCESS (BY INDEX ROWID) OF 'TB_BATCH_TRAN_CTRL'       
   1    0   NESTED LOOPS

scott@XE> select * from dept where deptno=10 and dname='ACCOUNTING';

- 星号是指谓词部分有展开
- access表示这个谓词条件会改变访问路径(表还是索引),是指通过索引可以得到记录,不必扫描所有数据
- filter表示谓词条件的值并不会影响数据的访问路径,只起到过滤的作用,是指没通过索引,要将先前的row source扫描一次,根据过滤条件剩下所要的记录

Execution Plan
----------------------------------------------------------
Plan hash value: 2852011669

---------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |     1 |    20 |     1   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    20 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | PK_DEPT |     1 |       |     0   (0)| 00:00:01 |
---------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("DNAME"='ACCOUNTING')
   2 - access("DEPTNO"=10)
   
-- 统计信息部分
--- db block gets(当前请求的块数目),当前模式块意思就是在操作中正好提取的块数目,而不是在一致性读的情况下而产生的块数。正常的情况下,一个查询提取的块是在查询开始的那个时间点上存在的数据块,当前块是在这个时刻存在的数据块,而不是在这个时间点之前或者之后的数据块数目。
--- consistent gets(数据请求总数在回滚段Buffer中的数据一致性读所需要的数据块),这里的概念是在处理你这个操作的时候需要在一致性读状态上处理多少个块,这些块产生的主要原因是因为由于在你查询的过程中,由于其他会话对数据块进行操 作,而对所要查询的块有了修改,但是由于我们的查询是在这些修改之前调用的,所以需要对回滚段中的数据块的前映像进行查询,以保证数据的一致性。这样就产生了一致性读。
--- physical reads(物理读),就是从磁盘上读取数据块的数量,如果这个值很高,说明要从磁盘请求大量的数据到Buffer Cache里,通常意味着系统里存在大量全表扫描的SQL语句,这会影响到数据库的性能,因此尽量避免语句做全表扫描,对于全表扫描的SQL语句,建议增 加相关的索引,优化SQL语句来解决。
--- logic reads(逻辑读),是指Oracle从内存读到的数据块数量。logic reads = consistent gets + db block gets。当在内存中找不到所需的数据块的话就需要从磁盘中获取,于是就产生了 phsical reads。
--- 数据缓冲区的使用命中率 = 1-(physical reads/(db block gets+consistent gets))
--- 查看数据缓冲区的命中率(查询出来的结果Buffer Cache的命中率应该在90%以上,否则需要增加数据缓冲区的大小)
    SELECT name,value FROM v$sysstat WHERE name IN ('db block gets','consistent gets','physical reads');

Statistics
----------------------------------------------------------
          0  recursive calls
          2  db block gets
          1  consistent gets
          0  physical reads
          0  redo size
        383  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22558114/viewspace-1097817/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2009-09-18

  • 博文量
    164
  • 访问量
    320474