需要建立一張表來(lái)記錄
成都創(chuàng)新互聯(lián)是一家專注于網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),水富網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:水富等地區(qū)。水富做網(wǎng)站價(jià)格咨詢:13518219792
explain plan SET statement_id='name' FOR (這里是你要調(diào)試的語(yǔ)句 )
SELECT
A.OPERATION,
OPTIONS,
OBJECT_NAME,
OBJECT_TYPE,
ID,
PARENT_ID
FROM
PLAN_TABLE A
WHERE
STATEMENT_ID='name'
ORDER BY
Id;
ID 'name'是一個(gè)標(biāo)識(shí),你可以自己取,字段有很多個(gè),以下是各個(gè)字段的解釋(可能格式不對(duì),你可以復(fù)制后看):
字段名 字段類型 含義
STATEMENT_ID VARCHAR2(30) explain PLAN 語(yǔ)句中所指定的最優(yōu)STATEMENT_ID 參數(shù)值, 如果在EXPLAN PLAN語(yǔ)句中沒有使用SET STATEMENT_ID,那么此值會(huì)被設(shè)為NULL。
REMARKS VARCHAR2(80) 與被解釋規(guī)劃的各步驟相關(guān)聯(lián)的注釋最長(zhǎng)可達(dá)80 字節(jié)
OPERATION VARCHAR2(30) 各步驟所執(zhí)行內(nèi)部操作的名稱在某條語(yǔ)句所產(chǎn)生的第一行中該列的可能取值如下DELETE STATEMENT INSERT STATEMENT SELECT STATEMENT UPDATE STATEMENT
OPTIONS VARCHAR2(30) 對(duì)OPERATION 列中所描述操作的變種
OBJECT_NODE VARCHAR2(128) 用于訪問(wèn)對(duì)象的數(shù)據(jù)庫(kù)鏈接database link 的名稱對(duì)于使用并行執(zhí)行的本地查詢?cè)摿心軌蛎枋霾僮髦休敵龅拇涡?/p>
OBJECT_OWNER VARCHAR2(30) 對(duì)于包含有表或索引的架構(gòu)schema 給出其所有者的名稱
OBJECT_NAME VARCHAR2(30) 表或索引的名稱
OBJECT_INSTANCE INTEGER 根據(jù)對(duì)象出現(xiàn)在原始o(jì)riginal 語(yǔ)句中的次序所給出的相應(yīng)次序編號(hào)就原始的語(yǔ)句文本而論其處理順序?yàn)樽宰笾劣易酝庀騼?nèi)景象擴(kuò)張view
OBJECT_TYPE VARCHAR2(30) 用于提供對(duì)象描述性信息的修飾符例如索引的NON-UNIQUE
OPTIMIZER VARCHAR2(255) 當(dāng)前優(yōu)化程序的模式
ID INTEGER 分配給執(zhí)行規(guī)劃各步驟的編號(hào)
PARENT_ID INTEGER 對(duì)ID 步驟的輸出進(jìn)行操作的下一個(gè)執(zhí)行步驟的ID
POSITION INTEGER 對(duì)于具有相同PARENT_ID 的步驟其相應(yīng)的處理次序
COST INTEGER 根據(jù)優(yōu)化程序的基于開銷的方法所估計(jì)出的操作開銷值對(duì)于使用基于規(guī)則方法的語(yǔ)句該列為空該列值沒有特定的測(cè)量單位它只是一個(gè)用于比較執(zhí)行規(guī)劃開銷大小的權(quán)重值
CARDINALITY INTEGER 根據(jù)基于開銷的方法對(duì)操作所訪問(wèn)行數(shù)的估計(jì)值
BYTES INTEGER 根據(jù)基于開銷的方法對(duì)操作所訪問(wèn)字節(jié)的估計(jì)
=============================================
你按照我說(shuō)的做,后面用
SELECT
*
FROM
PLAN_TABLE A
WHERE
STATEMENT_ID='name'
結(jié)果已經(jīng)很清楚了,全部滿足你的要求。
各列的具體含義上面已經(jīng)給出。
基于以前開發(fā)的一個(gè)用于監(jiān)控線程的CPU使用狀況的小工具 TopShow 我開發(fā)了一個(gè)用于追蹤Oracle內(nèi)部函數(shù)調(diào)用的追蹤器——OraTracer 你可以用該工具追蹤監(jiān)控Oracle多個(gè)內(nèi)部函數(shù)的調(diào)用情況 還可以嘗試探測(cè)函數(shù)的輸入?yún)?shù)的值 也可以打印追蹤點(diǎn)被觸發(fā)時(shí)的調(diào)用堆棧 追蹤可以設(shè)置在整個(gè)Oracle進(jìn)程的級(jí)別 也可以設(shè)置在某個(gè)線程以追蹤特定的會(huì)話
例子
捕獲oracle整個(gè)實(shí)例中被執(zhí)行的SQL語(yǔ)句
首先 在與可執(zhí)行文件相同的目錄下設(shè)置追蹤點(diǎn)文件 TracePoints txt 內(nèi)容如下
_opiprs *
_rpisplu *
_kprbprs
與函數(shù)名用空格相隔的數(shù)值為探測(cè)的參數(shù)數(shù)量 如果再加上 *N 則表示嘗試將雙字節(jié)數(shù)字作為指針對(duì)待 遞歸獲取其執(zhí)行的值 后面的數(shù)字為遞歸深度 例如 對(duì)于第一個(gè)追蹤點(diǎn) 函數(shù)名為 _opiprs 探測(cè) 個(gè)參數(shù) 遞歸探測(cè)指針數(shù)據(jù)的深度為
注意 # 為注釋符
然后從進(jìn)程列表中選擇 ORACLE EXE 不要選擇任何線程
最后 點(diǎn)擊 Trace 按鈕 一旦有語(yǔ)句被上述函數(shù)調(diào)用 你就可以從監(jiān)控窗口看到這些語(yǔ)句
SQL代碼
…
[ : : ]User call: _rpisplu (TID: )
[Args( )]:
select privilege# level from sysauth$ connect by grantee#=prior privilege# and privilege# start with grantee#=: and privilege#
× (=NULL)
[ : : ]User call: _rpisplu (TID: )
[Args( )]:
alter session set NLS_LANGUAGE= AMERICAN NLS_TERRITORY= AMERICA NLS_CURRENCY= $ NLS_ISO_CURRENCY= AMERICA NLS_NUMERIC_CHARACTERS= NLS_DATE_FORMAT= DD MON RR NLS_DATE_LANGUAGE= AMERICAN NLS_SORT= BINARY
xd (=NULL)
[ : : ]User call: _opiprs (TID: )
[Args( )]:
× cce (= × )
alter session set NLS_LANGUAGE= AMERICAN NLS_TERRITORY= AMERICA NLS_CURRENCY= $ NLS_ISO_CURRENCY= AMERICA NLS_NUMERIC_CHARACTERS= NLS_DATE_FORMAT= DD MON RR NLS_DATE_LANGUAGE= AMERICAN NLS_SORT= BINARY
xd (=NULL)
× bfe (= × )
[ : : ]User call: _rpisplu (TID: )
[Args( )]:
× (=NULL)
× (=NULL)
select sysdate + / ( * ) from dual
× (=NULL)
[ : : ]User call: _rpisplu (TID: )
[Args( )]:
× (=NULL)
× (=NULL)
DECLARE job BINARY_INTEGER := :job; next_date DATE := :mydate;? broken BOOLEAN := FALSE; BEGIN EMD_MAINTENANCE EXECUTE_EM_DBMS_JOB_PROCS(); :mydate := next_date; IF broken THEN :b := ; ELSE :b := ; END IF; END;
xd (=NULL)
…
點(diǎn)擊 Stop 按鈕 停止追蹤
例子 :
理解SQL是如何被執(zhí)行計(jì)劃驅(qū)動(dòng)執(zhí)行的
我們知道 查詢計(jì)劃實(shí)際上就是驅(qū)動(dòng)Oracle通過(guò)特定函數(shù)及順序來(lái)獲取數(shù)據(jù) 我們可以通過(guò)追蹤這些函數(shù)來(lái)理解執(zhí)行計(jì)劃
首先下載以下文件 解壓 重命名為 TracePoints txt 放到OraTracer exe所在目錄
然后獲取到你需要追蹤的會(huì)話的SPID
SQL代碼
HELLODBA select distinct spid from v$mystat m v$session s v$process p where s sid=m sid and s paddr=p addr;
SPID
————
從進(jìn)程列表中選擇ORACLE EXE = 從線程列表中選擇TID為 的線程 = 點(diǎn)擊 Trace 按鈕
在被追蹤的會(huì)話中執(zhí)行一條語(yǔ)句
SQL代碼
HELLODBA select * from demo t_test where owner= DEMO and object_name like T_TEST% ;
OWNER????????????????????????? OBJECT_NAME??????????????????? SUBOBJECT_NAME????????????????? OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE???????? CREATED
LAST_DDL_TIME?????? TIMESTAMP?????????? STATUS? T G S
—————————— —————————— —————————— ——— ————– —————— ———–
——– —————— —————— ——
DEMO?????????????????????????? T_TEST ??????????????????????? AAA???????????????????????????????? ????????? TABLE??????????????
: : : : : : : VALID?? N N N
注意 為了避免回滾調(diào)用也被追蹤 你最好在追蹤之前先運(yùn)行一次該語(yǔ)句
我們可以從追蹤窗口看到數(shù)據(jù)fetch調(diào)用情況
SQL代碼
[ : : ]User call: _qertbFetchByRowID (TID: )
[ : : ]User call: _qerixtFetch (TID: )
[ : : ]User call: _qertbFetchByRowID (TID: )
[ : : ]User call: _qerixtFetch (TID: )
有了這樣的追蹤記錄 你可以嘗試將他們與執(zhí)行計(jì)劃中節(jié)點(diǎn)映射
SQL代碼
HELLODBA select * from demo t_test where owner= DEMO and object_name like T_TEST% ;
Execution Plan
———————————————————
Plan hash value:
——————————————————————————————
| Id? | Operation?????????????????? | Name??????? | Rows? | Bytes | Cost (%CPU)| Time???? |
——————————————————————————————
|?? | SELECT STATEMENT??????????? |???????????? |???? |?? |???? ?? ( )| : : |
|?? |? TABLE ACCESS BY INDEX ROWID| T_TEST ???? |???? |?? |???? ?? ( )| : : | == _qertbFetchByRowID
|*? |?? INDEX RANGE SCAN????????? | T_TEST_IDX |???? |?????? |???? ?? ( )| : : | == _qerixtFetch
例子 :
打印某個(gè)特定函數(shù)被調(diào)用時(shí)的線程調(diào)用堆棧
我們這里追蹤 _kkeAdjSingTabCard 設(shè)置追蹤點(diǎn)
SQL代碼
_kkeAdjSingTabCard*
函數(shù)名后的 *N 指定輸出的調(diào)用個(gè)數(shù) 為無(wú)限制
然后獲取到你需要追蹤的會(huì)話的SPID
SQL代碼
HELLODBA select distinct spid from v$mystat m v$session s v$process p where s sid=m sid and s paddr=p addr;
SPID
————
從進(jìn)程列表中選擇ORACLE EXE = 從線程列表中選擇TID為 的線程 = 點(diǎn)擊 Trace 按鈕
在被追蹤的會(huì)話中解釋一條語(yǔ)句
SQL代碼
HELLODBA explain plan for select /*+full(t)*/ count(*) from demo t_test t;
Explained
我們就可以從監(jiān)控窗口獲取到該函數(shù)被調(diào)用時(shí)的整個(gè)調(diào)用堆棧的情況
SQL代碼
[ : : ]User call: _kkeAdjSingTabCard (TID: )
Call Stacks( ):
× (ORACLE EXE!_kkoitbp+ )
× c d (ORACLE EXE!_kkoijbad+ )
× d b (ORACLE EXE!_kkoCopyPreds+ )
× ee a (ORACLE EXE!_kkosta+ )
× d f c (ORACLE EXE!__PGOSF __apaRequestBindCapture+ )
× d (ORACLE EXE!_apagcp+ )
× d c (ORACLE EXE!_apafbr+ )
xea (ORACLE EXE!_opitcaNcp+ )
× b eb (ORACLE EXE!_kksMinimalTypeCheck+ )
× d (ORACLE EXE!_rpidrus+ )
× b ce (ORACLE EXE!_kksSetNLSHandle+ )
× e (ORACLE EXE!_kxsReleaseRuntimeLock+ )
× (ORACLE EXE!_kkscbt+ )
× e cf (ORACLE EXE!_kksParseCursor+ )
× f b (ORACLE EXE!_kksxscpat+ )
× e (ORACLE EXE!_opibrp+ )
× cd ed (ORACLE EXE!_kpodrd+ )
× cba c (ORACLE EXE!_kpocrs+ )
× e (ORACLE EXE!_opirip+ )
× feff (oramon dll!_ttcpro+ )
× a (ORACLE EXE!_opiodr+ )
× (ORACLE EXE!_opiino + )
× e (ORACLE EXE!_opirip+ )
× e (ORACLE EXE!_opidcl+ )
× a (ORACLE EXE!_ksdwri+ )
× (ORACLE EXE!_ssthrnfy+ )
× (ORACLE EXE!_opimai_init+ )
× (ORACLE EXE!_osnsoiint+ )
× c b (KERNEL dll!GetModuleFileNameA+ )
[Args( )]:
× e d
× e da
× a
×
lishixinzhi/Article/program/Oracle/201311/18739
用toad 的工具可以進(jìn)行跟蹤。查找toad的路徑 右鍵屬性 查找相應(yīng)文件夾 然后 找尋同級(jí)目錄下的 sql_monitor 這個(gè)工具就可以對(duì) Oracle運(yùn)行數(shù)據(jù)進(jìn)行跟蹤。