使用10046檢視執行計劃並讀懂trace檔案
轉自:https://blog.csdn.net/dataminer_2007/article/details/42040853
檢視 sql 執行計劃的方法有許多種, 10046 事件就是其中的一種. 與其他檢視 sql 執行計劃不同, 當我們遇到比較複雜的 sql 語句, 我們可以通過 10046 跟蹤 sql 得到執行計劃中每一個步驟的邏輯讀, 物理讀以及花費的時間等. 這種細粒度的跟蹤對於我們分析 sql 效能尤其有用.
一般來說, 使用 10046 事件得到 sql 執行計劃的步驟如下:
1. 啟用當前 session 10046 事件
2. 在當前 session 中執行 sql 語句
3. 關閉當前 session 10046 事件
執行完上述步驟後, 通常會自動生成一個 trace 檔案. 在 oracle 11g 中, trace 檔案一般放在$ORACLE_BASE/diag/rdbms/{database_name}/$ORACLE_SID/trace 目錄下. 如果使用 oradebug 啟用跟蹤 10046後, 可以使用 oradebug tracefile_name 得到剛剛生成的 trace 檔案的完整路徑。
NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ background_dump_dest string g:\app\davidd\diag\rdbms\david \david\trace
剛剛提到的 oradebug 啟用跟蹤 10046 事件, 我想大部分 dba 都會使用. oradebug 是個功能強大非常好用的工具, 使用 oradebug help 將會看到它的功能很多
SQL> oradebug help HELP [command] Describe one or all commands SETMYPID Debug current process SETOSPID <ospid> Set OS pid of process to debug SETORAPID <orapid> ['force'] Set Oracle pid of process to debug SETORAPNAME <orapname> Set Oracle process name to debug SHORT_STACK Get abridged OS stack CURRENT_SQL Get current SQL DUMP <dump_name> <lvl> [addr] Invoke named dump DUMPSGA [bytes] Dump fixed SGA DUMPLIST Print a list of available dumps EVENT <text> Set trace event in process SESSION_EVENT <text> Set trace event in session DUMPVAR <p|s|uga> <name> [level] Print/dump a fixed PGA/SGA/UGA variable DUMPTYPE <address> <type> <count> Print/dump an address with type info SETVAR <p|s|uga> <name> <value> Modify a fixed PGA/SGA/UGA variable PEEK <addr> <len> [level] Print/Dump memory POKE <addr> <len> <value> Modify memory WAKEUP <orapid> Wake up Oracle process SUSPEND Suspend execution RESUME Resume execution FLUSH Flush pending writes to trace file CLOSE_TRACE Close trace file TRACEFILE_NAME Get name of trace file LKDEBUG Invoke global enqueue service debugger NSDBX Invoke CGS name-service debugger -G <Inst-List | def | all> Parallel oradebug command prefix -R <Inst-List | def | all> Parallel oradebug prefix (return output SETINST <instance# .. | all> Set instance list in double quotes SGATOFILE <SGA dump dir> Dump SGA to file; dirname in double quotes DMPCOWSGA <SGA dump dir> Dump & map SGA as COW; dirname in double quotes MAPCOWSGA <SGA dump dir> Map SGA as COW; dirname in double quotes HANGANALYZE [level] [syslevel] Analyze system hang FFBEGIN Flash Freeze the Instance FFDEREGISTER FF deregister instance from cluster FFTERMINST Call exit and terminate instance FFRESUMEINST Resume the flash frozen instance FFSTATUS Flash freeze status of instance SKDSTTPCS <ifname> <ofname> Helps translate PCs to names WATCH <address> <len> <self|exist|all|target> Watch a region of memory DELETE <local|global|target> watchpoint <id> Delete a watchpoint SHOW <local|global|target> watchpoints Show watchpoints DIRECT_ACCESS <set/enable/disable command | select query> Fixed table access CORE Dump core without crashing process IPC Dump ipc information UNLIMIT Unlimit the size of the trace file PROCSTAT Dump process statistics CALL <func> [arg1] ... [argn] Invoke function with arguments
使用 oradebug 跟蹤 10046 命令如下:
SQL> oradebug setmypid
Statement processed.
// 啟用 10046 事件
SQL> oradebug event 10046 trace name context forever,level 12;
Statement processed.
SQL> select /*+ leading(t3) use_merge(t4) */ *
2 from t3, t4
3 where t3.id = t4.t3_id and t3.n = 1100;
10 rows selected.
// 在當前 session 關閉 10046 事件
SQL> oradebug event 10046 trace name context off;
Statement processed.
// 使用 oradebug tracefile_name 可以直接看到生成的 trace 檔案的位置
SQL> oradebug tracefile_name;
g:\app\davidd\diag\rdbms\david\david\trace\david_ora_2176.trc
其中, 10046 按照收集資訊的內容分為以下等級:
分析讀懂 trace 檔案
現在我們開啟 g:\app\davidd\diag\rdbms\david\david\trace\david_ora_2176.trc 看看生成的 trace 檔案的內容
<pre name="code" class="sql"><pre name="code" class="sql"><pre name="code" class="sql"><pre name="code" class="sql" style="font-size:14px;">PARSING IN CURSOR #22 len=92 dep=0 uid=0 oct=3 lid=0 tim=900460923321 hv=1624778336 ad='34671d90' sqlid='g0rdyg9hdh9m0'
select /*+ leading(t3) use_merge(t4) */ *
from t3, t4
where t3.id = t4.t3_id and t3.n = 1100
END OF STMT
PARSE #22:c=0,e=10777,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=3831111046,tim=900460923319
EXEC #22:c=0,e=29,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=3831111046,tim=900460923482
WAIT #22: nam='SQL*Net message to client' ela= 2 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=900460923512
FETCH #22:c=15625,e=23922,p=0,cr=119,cu=0,mis=0,r=1,dep=0,og=1,plh=3831111046,tim=900460947462
WAIT #22: nam='SQL*Net message from client' ela= 221 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=900460947755
WAIT #22: nam='SQL*Net message to client' ela= 2 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=900460947803
FETCH #22:c=0,e=71,p=0,cr=0,cu=0,mis=0,r=9,dep=0,og=1,plh=3831111046,tim=900460947864
STAT #22 id=1 cnt=10 pid=0 pos=1 obj=0 op='MERGE JOIN (cr=119 pr=0 pw=0 time=28 us cost=193 size=1280 card=10)'
STAT #22 id=2 cnt=1 pid=1 pos=1 obj=0 op='SORT JOIN (cr=15 pr=0 pw=0 time=0 us cost=6 size=63 card=1)'
STAT #22 id=3 cnt=1 pid=2 pos=1 obj=83550 op='TABLE ACCESS FULL T3 (cr=15 pr=0 pw=0 time=0 us cost=5 size=63 card=1)'
STAT #22 id=4 cnt=10 pid=1 pos=2 obj=0 op='SORT JOIN (cr=104 pr=0 pw=0 time=11 us cost=187 size=650000 card=10000)'
STAT #22 id=5 cnt=10000 pid=4 pos=1 obj=83552 op='TABLE ACCESS FULL T4 (cr=104 pr=0 pw=0 time=8603 us cost=29 size=650000 card=10000)'
從上面的 trace 檔案我們可以看出 sql 語句經過了 parse(解析) -> exec(執行) -> fetch(從遊標中獲取資料) 幾個過程, 其中第一句說明了當前跟蹤執行的 sql 語句的概況,比如使用遊標號, sql 語句的長度, 遞迴深度等等基本資訊:
PARSING IN CURSOR #22 len=92 dep=0 uid=0 oct=3 lid=0 tim=900460923321 hv=1624778336 ad='34671d90' sqlid='g0rdyg9hdh9m0'
接著, 下面的語句說明了 sql 語句具體的執行過程以及每一個步驟消耗 CPU 的時間等效能指標
PARSE #22:c=0,e=10777,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=3831111046,tim=900460923319
EXEC #22:c=0,e=29,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=3831111046,tim=900460923482
FETCH #22:c=15625,e=23922,p=0,cr=119,cu=0,mis=0,r=1,dep=0,og=1,plh=3831111046,tim=900460947462
以及執行過程中的發生的等待事
WAIT #22: nam='SQL*Net message to client' ela= 2 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=900460923512
最後顯示的是該遊標的執行計劃
STAT #22 id=1 cnt=10 pid=0 pos=1 obj=0 op='MERGE JOIN (cr=119 pr=0 pw=0 time=28 us cost=193 size=1280 card=10)'
STAT #22 id=2 cnt=1 pid=1 pos=1 obj=0 op='SORT JOIN (cr=15 pr=0 pw=0 time=0 us cost=6 size=63 card=1)'
STAT #22 id=3 cnt=1 pid=2 pos=1 obj=83550 op='TABLE ACCESS FULL T3 (cr=15 pr=0 pw=0 time=0 us cost=5 size=63 card=1)'
STAT #22 id=4 cnt=10 pid=1 pos=2 obj=0 op='SORT JOIN (cr=104 pr=0 pw=0 time=11 us cost=187 size=650000 card=10000)'
STAT #22 id=5 cnt=10000 pid=4 pos=1 obj=83552 op='TABLE ACCESS FULL T4 (cr=104 pr=0 pw=0 time=8603 us cost=29 size=650000 card=10000
例如, 執行步驟 merge join 消耗的邏輯讀為 119, 物理讀為 0, 耗費的時間為 28 us, 成本 cost 193,返回 10 條記錄。
使用 tkprof 命令翻譯 trace 檔案
我們也可以使用 tkprof 命令對 trace 檔案進行翻譯,得到一個容易理解的 trace 彙總報表檔案
C:\Documents and Settings\davidd> tkprof g:\app\davidd\diag\rdbms\david\david\trace\david_ora_2176.trc d:\trace.trc
TKPROF: Release 11.2.0.1.0 - Development on Thu Dec 18 18:51:44 2014
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
tkprof 翻譯的 trace 檔案的彙總報表如下
Trace file: g:\app\davidd\diag\rdbms\david\david\trace\david_ora_2176.trc
Sort options: default
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
select /*+ leading(t3) use_merge(t4) */ *
from t3, t4
where t3.id = t4.t3_id and t3.n = 1100
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 119 0 10
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.00 0.00 0 119 0 10
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS
Rows Row Source Operation
------- ---------------------------------------------------
10 MERGE JOIN (cr=119 pr=0 pw=0 time=0 us cost=193 size=1280 card=10)
1 SORT JOIN (cr=15 pr=0 pw=0 time=0 us cost=6 size=63 card=1)
1 TABLE ACCESS FULL T3 (cr=15 pr=0 pw=0 time=0 us cost=5 size=63 card=1)
10 SORT JOIN (cr=104 pr=0 pw=0 time=0 us cost=187 size=650000 card=10000)
10000 TABLE ACCESS FULL T4 (cr=104 pr=0 pw=0 time=8733 us cost=29 size=650000 card=10000)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 20.23 20.23
********************************************************************************
OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 119 0 10
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.00 0.00 0 119 0 10
Misses in library cache during parse: 1
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 3 0.00 0.00
SQL*Net message from client 3 20.23 30.20
OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 0 0.00 0.00 0 0 0 0
Execute 0 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 0 0.00 0.00 0 0 0 0
Misses in library cache during parse: 0
1 user SQL statements in session.
0 internal SQL statements in session.
1 SQL statements in session.
********************************************************************************
Trace file: g:\app\davidd\diag\rdbms\david\david\trace\david_ora_2176.trc
Trace file compatibility: 11.1.0.7
Sort options: default
1 session in tracefile.
1 user SQL statements in trace file.
0 internal SQL statements in trace file.
1 SQL statements in trace file.
1 unique SQL statements in trace file.
122 lines in trace file.
0 elapsed seconds in trace file.
其中,Misses in library cache during parse :1 意思是解析的時候庫快取丟失遊標, 也就是說發生了一次硬解析。