查看本地會話的SQL或PL/SQL的執行計劃可以在本地執行 alter session set sql_trace=true; 和打開捕獲 10046事件 alter session set events '10046 trace name context forever,level 12';10046事件的 level 值說明如下:level 1:和 sql trace 作用相同(跟蹤sql語句,包括解析、執行、提取、提交和回滾等)level 4: level 1+ SQL的梆定變量信息level 8: level 1+ SQL的等待事件信息level 12: level 4 + level 8查看本地會話執行的SQL執行計劃也可以用 set autotrace on 或 explain plan for...,不過這兩種方式捕獲的執行計劃可能不準確的,10046事件和 dbms_xplan.display_cursor 返回的執行計劃信息纔是準確的。如果要查看遠程其它會話的SQL或PL/SQL語句的執行情況呢?那麼可以使用Oracle提供的系統包和存儲過程:dbms_system.set_sql_trace_in_session(sid,serial#,sql_trace); --開啓SQL Trace,這個相當於在本地會話執行 alter session set sql_trace=true;sid 參數等於 v$session.sid;serial# 參數等於 v$session.serial#;sql_trace 是邏輯布爾值,true表示開啓sql_trace,fasle表示關閉。 dbms_monitor.session_trace_enable(session_id,serial_num,waits,binds); --打開10046事件捕獲SQL或PL/SQL語句的執行計劃和等待事件等信息。 session_id 參數等於 v$session.sid; serial_num 參數等於 v$session.serial#;waits 參數表示記錄等待事件的信息;binds 參數表示記錄梆定變量的信息。以下通過事例來說明,分別開兩個session:session 1登錄的用戶是sys(用於執行系統包和過程打開和關閉遠程會話(session 2) 的sql trace 和 10086;session 2登錄的用戶是tuser,用於執行SQL語句,以便session 1捕獲其的SQL執行計劃等信息。session 1:
查詢 session 2 的 sid和serial#: 04:22:59 SYS@orcl*SQL> select sid,serial# from v$session
04:23:05 2 where username='TUSER' and status in ('ACTIVE','INACTIVE');
SID SERIAL#
------------------ ------------------
25 1002
或者在 session 2中執行 select sid,serial# from v$session where sid=userenv('sid'); 或者
select sid,serial# from v$session where sid=(select distinct sid from v$mystat);
查看相關的 sid和serial# 。
開啓 session 的SQL Trace:
exec dbms_system.set_sql_trace_in_session(sid=>25,serial#=>1002,sql_trace=>true);session 2:
在 session 2 中執行SQL:04:20:32 TUSER@orcl*SQL> select * from emp where empno>7800;
查詢session 2的trace跟蹤文件位置:04:25:54 TUSER@orcl*SQL> select s.sid,s.process,p.addr,p.spid,p.tracefile
04:25:57 2 from v$process p,v$session s
04:25:57 3 where p.addr=s.paddr
04:25:57 4 and s.sid=userenv('sid');
SID PROCESS ADDR SPID TRACEFILE
------------------ ---------- -------- ---------- --------------------------------------------------------------------------
25 13840 38BCE46C 13842 /oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_13842.trc
查看 session 2 的 trace 文件記錄的SQL的執行情況信息:oracle@SLES11:/oracle/diag/rdbms/orcl/orcl/trace> less orcl_ora_13842.trcPARSING IN CURSOR #3 len=34 dep=0 uid=91 oct=3 lid=91 tim=1452975876173470 hv=1639899136 ad='338cf680' sqlid='b2mdjv5hvxs00'
select * from emp where empno>7800
END OF STMT
PARSE #3:c=8001,e=6957,p=2,cr=42,cu=0,mis=1,r=0,dep=0,og=1,plh=3956160932,tim=1452975876173470
EXEC #3:c=0,e=9,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=3956160932,tim=1452975876173520
FETCH #3:c=0,e=31357,p=2,cr=3,cu=0,mis=0,r=1,dep=0,og=1,plh=3956160932,tim=1452975876204942
FETCH #3:c=0,e=33,p=0,cr=1,cu=0,mis=0,r=5,dep=0,og=1,plh=3956160932,tim=1452975876205507
STAT #3 id=1 cnt=6 pid=0 pos=1 obj=74974 op='TABLE ACCESS FULL EMP (cr=4 pr=2 pw=0 time=0 us cost=3 size=114 card=3)'
上面顯示的是SQL的解析、執行、提取數據、執行計劃等信息。其中什麼cpu時間,執行用時,一致讀,當前讀等各項參數的含義網上說得很詳細,這裏不再詳述。
session 1:
在session 1中關閉遠程會話的 sql trace 功能:
04:26:38 SYS@orcl*SQL> exec dbms_system.set_sql_trace_in_session(25,1002,false);
再在 session 1 中開啓 seesion 2 的10046事件:
04:26:42 SYS@orcl*SQL> exec dbms_monitor.session_trace_enable(25,1002,waits=>true,binds=>true);
並將在 sys 用戶創建的 f_test 測試樣例函數授權給tuser用戶:
grant execute on sys.f_test to tuser;session 2:
在 session 2 中執行SQL和使用梆定變量:04:26:01 TUSER@orcl*SQL> var a number
04:30:03 TUSER@orcl*SQL> var b number
04:30:07 TUSER@orcl*SQL> var rs varchar2(200)
04:30:19 TUSER@orcl*SQL> exec :a:=1
04:31:09 TUSER@orcl*SQL> exec :b:=2
04:31:32 TUSER@orcl*SQL> exec :rs:=sys.f_test(:a,:b);
04:32:24 TUSER@orcl*SQL> print rs
RS
----------------------------------
The result:1 + 2 = 3
04:32:26 TUSER@orcl*SQL> select sys.f_test(:a,:b) from dual;
SYS.F_TEST(:A,:B)
------------------------------------------------------------
The result:1 + 2 = 3
查看 session 2 的 trace 文件檢查執行SQL和函數使用的梆定變量等信息:
=====================
PARSING IN CURSOR #4 len=34 dep=0 uid=91 oct=3 lid=91 tim=1452976366537538 hv=67575608 ad='384dafbc' sqlid='6ngw7f420f7ts'
select sys.f_test(:a,:b) from dual
END OF STMT
PARSE #4:c=4001,e=581,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=1452976366537537
BINDS #4:
Bind#0
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=03 fl2=1000000 frm=00 csi=00 siz=48 off=0
kxsbbbfp=b6999a4c bln=22 avl=02 flg=05
value=1 --這個就是梆定變量 :a 的值
Bind#1
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=03 fl2=1000000 frm=00 csi=00 siz=0 off=24
kxsbbbfp=b6999a64 bln=22 avl=02 flg=01
value=2 --這個就是梆定變量 :b 的值
EXEC #4:c=0,e=3643,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=1388734953,tim=1452976366541327
WAIT #4: nam='SQL*Net message to client' ela= 4 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1452976366541455
FETCH #4:c=0,e=173,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=1388734953,tim=1452976366541684
STAT #4 id=1 cnt=1 pid=0 pos=1 obj=0 op='FAST DUAL (cr=0 pr=0 pw=0 time=0 us cost=2 size=0 card=1)'
WAIT #4: nam='SQL*Net message from client' ela= 2425 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1452976366544303
FETCH #4:c=0,e=3,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,plh=1388734953,tim=1452976366544438
WAIT #4: nam='SQL*Net message to client' ela= 3 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1452976366544494
WAIT #4: nam='SQL*Net message from client' ela= 1073 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1452976366545603
=====================
還可以使用 tkprof 工具將 10046事件的trace文件格式化,以更直觀的方式更行顯示,但是用tkprof 格式化的trace 文件是看不到梆定變量信息的。(完)