日期:2014-05-16 浏览次数:20531 次
我们先用一个小表来,来说明一下,oracle执行计划该注意哪些地方。
hr@ORCL> set autotrace traceonly
hr@ORCL> select * from t;
模糊比较两条sql的优劣时,建议先查看以下两个值:
Cost (%CPU):cpu代价,这个值要代数和。比如,这里是3+3=6
consistent gets:这个值一般要多执行几次!让他稳定下来,才有比较的意义。
Execution Plan :
----------------------
Plan hash value: 1601196873
下面这个计划看的方法:由里到外,由上到下
--------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     6 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| T    |     1 |     6 |     3   (0)| 00:00:01 |
--------------------------------------
Statistics
----------------------
        228  recursive calls  --访问数据字典得到元数据。第二次执行相同语句,递归调用基本为零。
          0  db block gets  -- 指DML语句所得到的数据块个数
         33  consistent gets  --重要!!指select语句所得到的数据块个数
          8  physical reads --硬盘上读出的数据
          0  redo size   --产生的日志
        414  bytes sent via SQL*Net to client       --网络流量指标
        385  bytes received via SQL*Net from client  --网络流量指标
          2  SQL*Net roundtrips to/from client
          4  sorts (memory)
          0  sorts (disk)
          1  rows processed
    现在,我们用一个大表,来把执行计划列出来。
sys@ORCL> select * from dba_objects; 50393 rows selected. Execution Plan ---------------------- Plan hash value: 2127761497 ---------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------- | 0 | SELECT STATEMENT | | 48669 | 8412K| 145 (5)| 00:00:02 | | 1 | VIEW | DBA_OBJECTS | 48669 | 8412K| 145 (5)| 00:00:02 | | 2 | UNION-ALL | | | | | | |* 3 | FILTER | | | | | | |* 4 | HASH JOIN | | 51423 | 4670K| 143 (5)| 00:00:02 | | 5 | TABLE ACCESS FULL | USER$ | 62 | 868 | 2 (0)| 00:00:01 | |* 6 | TABLE ACCESS FULL | OBJ$ | 51423 | 3967K| 140 (4)| 00:00:02 | |* 7 | TABLE ACCESS BY INDEX ROWID| IND$ | 1 | 8 | 2 (0)| 00:00:01 | |* 8 | INDEX UNIQUE SCAN | I_IND1 | 1 | | 1 (0)| 00:00:01 | | 9 | TABLE ACCESS BY INDEX ROWID | LINK$ | 1 | 88 | 0 (0)| 00:00:01 | | 10 | NESTED LOOPS | | 1 | 102 | 2 (0)| 00:00:01 | | 11 | TABLE ACCESS FULL | USER$ | 62 | 868 | 2 (0)| 00:00:01 | |* 12 | INDEX RANGE SCAN | I_LINK1 | 1 | | 0 (0)| 00:00:01 | ----------------------------------------------------------
    其实,前两列是颗二叉树。我们可以借助v$sql_plan视图,很容易把这颗树给画出来。
sys@ORCL> select id,parent_id                       
  2         from v$sql_plan
  3        where plan_hash_value=2127761497;
        ID  PARENT_ID
---------- ----------
         0
         1          0
         2          1
         3          2
         4          3
         5          4
         6          4
         7          3
         8          7
         9          2
        10          9
        11         10
        12         10
    通过上面的子节点和父节点,可得图如下:
    把这颗二叉树中序遍历,就可以得到这条sql的执行顺序了:5,6,4,8,7,3,11,12,10,9,2,1,0
注意:
1)图中的数字,是从v$sql_plan查出来的。
2)画图总是从左孩子开始
3)二叉树要做中序遍历才是sql的执行顺序