我們以下面的一個例子來講解
這裡做個補充:trace的類型一共有以下幾種
序號
命令
解釋
1
SET AUTOTRACE OFF
此為默認值,即關閉Autotrace
2
SET AUTOTRACE ON EXPLAIN
只顯示執行計劃
3
SET AUTOTRACE ON STATISTICS
只顯示執行的統計信息
4
SET AUTOTRACE ON
包含2,3兩項內容
5
SET AUTOTRACE TRACEONLY
與ON相似,但不顯示語句的執行結果
我喜歡SET AUTOTRACE TRACEONLY,我們以後的例子都是基於這種方式的
[sql] view plaincopyprint?
SQL> select * from departments a where a.department_id in (select b.department_id from employees b where b.employee_id=205); Execution Plan ---------------------------------------------------------- Plan hash value: 2782876085 ---------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 27 | 2 (0)| 00:00:01 | | 1 | NESTED LOOPS | | 1 | 27 | 2 (0)| 00:00:01 | | 2 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 1 | 7 | 1 (0)| 00:00:01 | |* 3 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK | 1 | | 0 (0)| 00:00:01 | | 4 | TABLE ACCESS BY INDEX ROWID| DEPARTMENTS | 27 | 540 | 1 (0)| 00:00:01 | |* 5 | INDEX UNIQUE SCAN | DEPT_ID_PK | 1 | | 0 (0)| 00:00:01 | ---------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("B"."EMPLOYEE_ID"=205) 5 - access("A"."DEPARTMENT_ID"="B"."DEPARTMENT_ID") Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 4 consistent gets 0 physical reads 0 redo size 749 bytes sent via SQL*Net to client 492 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed讓我們來一行一行的看:
一、表部分
1、Plan hash value:
[sql] view plaincopyprint?
Plan hash value: 2782876085這一行是這一條語句的hash值,我們知道oracle對每條語句產生的執行計劃放在share pool裡面,第一次要經過硬解析,產生hash值。下次再執行該語句時候比較hash值,如果相同就不要執行硬解析。
2、Operation( 操作)
這裡的東西就多了,就是把sql進行分解,讓我一起看看上的sql,這段sql的第一步是employee_id=25,這裡我們employee_id上面建了主鍵,建主鍵默認創建唯一索引。這裡是用“=”進行限制的,所以走的unique scan方式。其他方式參考Oracle執行計劃 講解(一)內容
還有一個知識點,就是要知道表鏈接操作,見我的另外一篇文章()
3、Name(被操作的對象)
比如上例中的第二行operation(TABLE ACCESS BY INDEX ROWID)這裡的TABLE對象為EMPLOYEES
4、Row,有的地方也叫Cardinality(用plsqldev裡面解釋計劃窗口)
這裡是數據查詢的行數,比如說上個例子第4行, departments 這張表就要掃描27行,然後和子查詢(select b.department_id from employees b where b.employee_id=205)的值進行比較。如果使用=(注:大部分時候是不能用=來替換,這裡是特例)就不一樣了。
[sql] view plaincopyprint?
SQL> select * from departments a where a.department_id = (select b.department_id from employees b where b.employee_id=205); Execution Plan ---------------------------------------------------------- Plan hash value: 3449260133 ----------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 20 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID | DEPARTMENTS | 1 | 20 | 1 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | DEPT_ID_PK | 1 | | 0 (0)| 00:00:01 | | 3 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 1 | 7 | 1 (0)| 00:00:01 | |* 4 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK | 1 | | 0 (0)| 00:00:01 | ----------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("A"."DEPARTMENT_ID"= (SELECT /*+ */ "B"."DEPARTMENT_ID" FROM "EMPLOYEES" "B" WHERE "B"."EMPLOYEE_ID"=205)) 4 - access("B"."EMPLOYEE_ID"=205) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 4 consistent gets 0 physical reads 0 redo size 749 bytes sent via SQL*Net to client 492 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed
5、Byte
掃描的數據的字節數
6、Cost
這裡上次講過了,這裡簡單說下吧。
cost沒有單位,是一個相對值,是sql文以cbo方式解析執行時,供oracle用來評估cbo成本,選擇執行計劃用的。
公式:Cost=(Single block I/O cost+ Multiblock I/O cost+ CPU cost)/sreadtim
沒有明確的含義,不過對比時就非常有用了。
7、Time
每段執行的時間
二、Predicate Information
這裡列出的是過濾條件,一共有兩種:
1、索引(access)
如上例中的access("B"."EMPLOYEE_ID"=205),這裡使用索引作為過濾條件
2、非索引(filter),看下面這裡例子
[sql] view plaincopyprint?
SQL> select employee_id from employees c where c.first_name = 'Steven' 2 3 ; Execution Plan ---------------------------------------------------------- Plan hash value: 1445457117 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 11 | 3 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| EMPLOYEES | 1 | 11 | 3 (0)| 00:00:01 | ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("C"."FIRST_NAME"='Steven') Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 8 consistent gets 0 physical reads 0 redo size 574 bytes sent via SQL*Net to client 492 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2 rows processed
三、Statistics(統計信息)
這裡是重點要說的,如果看累了,可以去喝口水。O(∩_∩)O~
AUTOTRACE Statistics列解釋
序號
列名
解釋
1