內容主要來自看書學習的筆記,如下記錄了常見查詢執行計劃的方法。
2.2 如何查看執行計劃
1.explain plan
2.dbms_xplan包
3.autotrace
4.10046事件
5.10053事件
6.awr/statspack報告(@?/rdbms/admin/awrsqrpt)
7.腳本(display_cursor_9i.sql)
2.2.1 explain plan
explain plan for sql
select * from table(dbms_xplan.display);
SQL> explain plan for select * from emp;
已解釋。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------
Plan hash value: 3956160932
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 12 | 468 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| EMP | 12 | 468 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------
已選擇8行。
其原理是oracle會把explain plan的sql的執行計劃寫入plan_table$,執行查詢 table(dbms_xplan.display),會把其格式化後輸出。
plan_table$是一個on commit preserve rows的global temporary table,各個session只能看到自己的,互不干擾。
2.2.2 dbms_xplan包
按照場景不同,有以下四種方法:
1.select * from table(dbms_xplan.display);
2.select * from table(dbms_xplan.display_cursor(null,null,’advanced’));
3.select * from table(dbms_xplan.display_cursor(’sql_id/hash_value’,child_cursor_number,’advanced’));
4.select * from table(dbms_xplan.display_awr(’sql_id'));
第一種方法就是explain plan。
第二種方法是查看剛剛執行過的sql的執行計劃。
第三種方法是查看指定sql的執行計劃,需要sql_id或hash_value,還有child_number(v$sql)。
select sql_text,sql_id,hash_value,child_number from v$sql where sql_text like ‘%xxxx%’;
第四種方法是查看指定sql所有歷史執行計劃,第二、第三種方法需要其sql執行計劃還在shared pool種,如果被age out出shared pool(v$sqlarea中查詢不到),只要其被采集到awr repository中,就可以用第四種方法查看。(v$sqlarea中的version_count代表有幾個執行計劃)
select sql_text,sql_id,version_count,executions from v$sqlarea where sql_text like ‘xxx’; —可以查詢到
exec dbms_workload_repository.create_snapshot; --采集awr
alter system flush shared_pool; —清理shared pool
select sql_text,sql_id,version_count,executions from v$sqlarea where sql_text like ‘xxx’; —查詢不到
此時已經無法使用第二、第三種方法查看。但是第四種方法無法顯示謂詞條件,不完美。
2.2.3 autotrace
set autotrace {off|on|traceonly}
[explain]
[statistics]
不僅可以得到執行計劃,還可以得到資源消耗量。
set autotrace on = set auto on —結果集+執行計劃+消耗資源量
set autotrace off = set autot off --關閉
set autotrace traceonly = set auto trace —執行計劃+消耗資源量
set autotrace traceonly explain = set autot trace exp --執行計劃
set autotrace traceonly statistics = set autot trace stat —消耗資源量
2.2.4 10046事件與tkprof
1.激活10046事件
alter session set events '10046 trace name context forever,level 12';
oradebug setmypid;
oradebug event 10046 trace name context forever,level 12;
2.執行sql
3.關閉10046事件
alter session set events '10046 trace name context off'
oradebug event 10046 trace name context off
4.tkprof tracefile outputfile
注意oradebug只能sys用戶使用,不是很方便。
使用display_cursor_9i.sql
@/xxx/display_cursor_9i.sql hash_value child_number
使用printsql
使用sys用戶@/xxx/printsql.prc創建過程
set serveroutput on size 1000000
exec printsql(xxxxx,'SID')
exec printsql(xxxxx,'SPID')
2.3真實的執行計劃
explain plan、set autotrace、select * from table(dbms_xplan.display)都有可能不准,主要是因為綁定變量,在默認開啟綁定變量窺探bind peeking的情況下,以上方法的執行計劃只是半成品。
2.4執行計劃的執行順序
先從最開頭一直連續往右看,直到看到最右邊的並列的地方;對於不並列的,靠右先執行;如果見到並列的,就從上往下看,對於並列的部分,靠上先執行。