TKPROF使用學(xué)習(xí)
?
??? Tkprof工具可用來(lái)格式化sql trace產(chǎn)生的文件,讓你更容易看懂trace的內(nèi)容
?
?
用法:
?
tkprof tracefile outputfile [explain= ] [table= ] [print= ] [insert= ] [sys= ] [sort= ] ...
?
?
參數(shù)說(shuō)明:
?
tracefile:你要分析的trace文件
outputfile:格式化后的文件
explain=user/password@connectstring
table=schema.tablename
??? 注1:這兩個(gè)參數(shù)是一起使用的,通過(guò)連接數(shù)據(jù)庫(kù)對(duì)在trace文件中出現(xiàn)的每條sql語(yǔ)句查看執(zhí)行計(jì)劃,并將之輸出到outputfile中
???
注2:該table必須是數(shù)據(jù)庫(kù)中不存在的,如果存在會(huì)報(bào)錯(cuò)
print=n:只列出最初N個(gè)sql執(zhí)行語(yǔ)句
insert=filename:會(huì)產(chǎn)生一個(gè)sql文件,運(yùn)行此文件可將收集到的數(shù)據(jù)insert到數(shù)據(jù)庫(kù)表中
sys=no:過(guò)濾掉由sys執(zhí)行的語(yǔ)句
record=filename:可將非嵌套執(zhí)行的sql語(yǔ)句過(guò)濾到指定的文件中去
waits=yes|no:是否統(tǒng)計(jì)任何等待事件
aggregate=yes|no:是否將相同sql語(yǔ)句的執(zhí)行信息合計(jì)起來(lái),默認(rèn)為yes
sort=
option:設(shè)置排序選項(xiàng),選項(xiàng)如下:
??? prscnt:number of times parse was called
??? prscpu:cpu time parsing
??? prsela:elapsed time parsing
??? prsdsk:number of disk reads during parse
??? prsqry:number of buffers for consistent read during parse
??? prscu:number of buffers for current read during parse
??? prsmis:number of misses in library cache during parse
??? execnt:number of execute was called
??? execpu:cpu time spent executing
??? exeela:elapsed time executing
??? exedsk:number of disk reads during execute
??? exeqry:number of buffers for consistent read during execute
??? execu:number of buffers for current read during execute
??? exerow:number of rows processed during execute
??? exemis:number of library cache misses during execute
??? fchcnt:number of times fetch was called
??? fchcpu:cpu time spent fetching
??? fchela:elapsed time fetching
??? fchdsk:number of disk reads during fetch
??? fchqry:number of buffers for consistent read during fetch
??? fchcu:number of buffers for current read during fetch
??? fchrow:number of rows fetched
??? userid:userid of user that parsed the cursor
??? prscpu:cpu time parsing
??? prsela:elapsed time parsing
??? prsdsk:number of disk reads during parse
??? prsqry:number of buffers for consistent read during parse
??? prscu:number of buffers for current read during parse
??? prsmis:number of misses in library cache during parse
??? execnt:number of execute was called
??? execpu:cpu time spent executing
??? exeela:elapsed time executing
??? exedsk:number of disk reads during execute
??? exeqry:number of buffers for consistent read during execute
??? execu:number of buffers for current read during execute
??? exerow:number of rows processed during execute
??? exemis:number of library cache misses during execute
??? fchcnt:number of times fetch was called
??? fchcpu:cpu time spent fetching
??? fchela:elapsed time fetching
??? fchdsk:number of disk reads during fetch
??? fchqry:number of buffers for consistent read during fetch
??? fchcu:number of buffers for current read during fetch
??? fchrow:number of rows fetched
??? userid:userid of user that parsed the cursor
可根據(jù)自己的需要設(shè)置排序
?
?
舉例:
?
1.列出前2條sql語(yǔ)句的執(zhí)行情況:
?
C:\>tkprof c:\oc_ora_2892.trc c:\cc.txt print=2
?
2.將數(shù)據(jù)保存到數(shù)據(jù)庫(kù):
?
C:\>tkprof c:\oc_ora_2892.trc c:\cc.txt insert=c:\insert.sql
?
執(zhí)行后會(huì)在c:\產(chǎn)生insert.sql文件,執(zhí)行該文件即可將數(shù)據(jù)保存到數(shù)據(jù)庫(kù),以下為insert.sql部分內(nèi)容:
?
REM Edit and/or remove the following CREATE TABLE
REM statement as your needs dictate.
CREATE TABLE tkprof_table
(
date_of_insert DATE
,cursor_num NUMBER
,depth NUMBER
,user_id NUMBER
,parse_cnt NUMBER
,parse_cpu NUMBER
,parse_elap NUMBER
,parse_disk NUMBER
,parse_query NUMBER
,parse_current NUMBER
,parse_miss NUMBER
,exe_count NUMBER
,exe_cpu NUMBER
,exe_elap NUMBER
,exe_disk NUMBER
,exe_query NUMBER
,exe_current NUMBER
,exe_miss NUMBER
,exe_rows NUMBER
,fetch_count NUMBER
,fetch_cpu NUMBER
,fetch_elap NUMBER
,fetch_disk NUMBER
,fetch_query NUMBER
,fetch_current NUMBER
,fetch_rows NUMBER
,ticks NUMBER
,sql_statement LONG
);
INSERT INTO tkprof_table VALUES
(
SYSDATE, 1, 0, 61, 1, 0, 418, 0, 0, 0, 1
, 1, 15625, 1435, 0, 0, 0, 0, 0
, 4, 0, 4417, 0, 24, 0, 36, 13450151
, ’select * from tblinventoryhistory
‘);
REM statement as your needs dictate.
CREATE TABLE tkprof_table
(
date_of_insert DATE
,cursor_num NUMBER
,depth NUMBER
,user_id NUMBER
,parse_cnt NUMBER
,parse_cpu NUMBER
,parse_elap NUMBER
,parse_disk NUMBER
,parse_query NUMBER
,parse_current NUMBER
,parse_miss NUMBER
,exe_count NUMBER
,exe_cpu NUMBER
,exe_elap NUMBER
,exe_disk NUMBER
,exe_query NUMBER
,exe_current NUMBER
,exe_miss NUMBER
,exe_rows NUMBER
,fetch_count NUMBER
,fetch_cpu NUMBER
,fetch_elap NUMBER
,fetch_disk NUMBER
,fetch_query NUMBER
,fetch_current NUMBER
,fetch_rows NUMBER
,ticks NUMBER
,sql_statement LONG
);
INSERT INTO tkprof_table VALUES
(
SYSDATE, 1, 0, 61, 1, 0, 418, 0, 0, 0, 1
, 1, 15625, 1435, 0, 0, 0, 0, 0
, 4, 0, 4417, 0, 24, 0, 36, 13450151
, ’select * from tblinventoryhistory
‘);
?
3.提取sql執(zhí)行語(yǔ)句:
?
C:\>tkprof c:\oc_ora_2892.trc c:\cc.txt record=sqlstr.sql
?
sqlstr.sql中的內(nèi)容:
?
alter session set sql_trace=true ;
alter session set events '10046 trace name context forever,level 12';
select * from tblinventoryhistory ;
select * from tblorder ;
select * from tblproduct ;
select * from tbluser ;
select * from tblroute ;
alter session set events '10046 trace name context forever,level 12';
select * from tblinventoryhistory ;
select * from tblorder ;
select * from tblproduct ;
select * from tbluser ;
select * from tblroute ;
?
4.產(chǎn)生執(zhí)行計(jì)劃:
?
C:\>tkprof c:\oc_ora_2892.trc c:\ff.txt explain=ocuser/ocuser table=ocuser.test1
?
在產(chǎn)生的ff.txt文件中會(huì)體現(xiàn)其執(zhí)行計(jì)劃:
?
Rows Execution Plan
——- —————————————————
0 SELECT STATEMENT GOAL: CHOOSE
0 TABLE ACCESS (FULL) OF 'TBLROUTE'
——- —————————————————
0 SELECT STATEMENT GOAL: CHOOSE
0 TABLE ACCESS (FULL) OF 'TBLROUTE'
?
?
小技巧:
?
1.如何查找你產(chǎn)生的trace文件:
?
可用eygle寫(xiě)的腳本去查找:
?
SQL> select d.value || '\' || lower(rtrim(i.instance, chr(0))) || '_ora_' ||
? 2???????? p.spid || '.trc' trace_file_name
? 3??? from (select p.spid
? 4??????????? from sys.v$mystat m, sys.v$session s, sys.v$process p
? 5?????????? where m.statistic# = 1
? 6???????????? and s.sid = m.sid
? 7???????????? and p.addr = s.paddr) p,
? 8???????? (select t.instance
? 9??????????? from sys.v$thread t, sys.v$parameter v
10?????????? where v.name = 'thread'
11???????????? and (v.value = 0 or t.thread# = to_number(v.value))) i,
12???????? (select value from sys.v$parameter where name = 'user_dump_dest') d;
? 2???????? p.spid || '.trc' trace_file_name
? 3??? from (select p.spid
? 4??????????? from sys.v$mystat m, sys.v$session s, sys.v$process p
? 5?????????? where m.statistic# = 1
? 6???????????? and s.sid = m.sid
? 7???????????? and p.addr = s.paddr) p,
? 8???????? (select t.instance
? 9??????????? from sys.v$thread t, sys.v$parameter v
10?????????? where v.name = 'thread'
11???????????? and (v.value = 0 or t.thread# = to_number(v.value))) i,
12???????? (select value from sys.v$parameter where name = 'user_dump_dest') d;
?
TRACE_FILE_NAME
——————————————————————————–
/opt/oracle/admin/hsjf/udump/hsjf_ora_1026.trc
——————————————————————————–
/opt/oracle/admin/hsjf/udump/hsjf_ora_1026.trc
?
2.sort選項(xiàng)可同時(shí)用多個(gè),做法是用括號(hào)括起來(lái),中間用逗號(hào)分割:
?
C:\>tkprof c:\oc_ora_2892.trc c:\cc.txt sort=(prsela, exeela, fchela)
注意:最后排序是按照各個(gè)選項(xiàng)的數(shù)字之和進(jìn)行排序,類似于order by (sort1+sort2+sort3),而不是order by sort1,sort2,sort3
注意:最后排序是按照各個(gè)選項(xiàng)的數(shù)字之和進(jìn)行排序,類似于order by (sort1+sort2+sort3),而不是order by sort1,sort2,sort3
?
?
?
oracle性能優(yōu)化:如何讀懂tkprof
?
??? 感覺(jué)這方面的資料都比較少,目前知道的:(將陸續(xù)整理)
CALL :每次SQL語(yǔ)句的處理都分成以下三個(gè)部分
? Parse:這步將SQL語(yǔ)句轉(zhuǎn)換成執(zhí)行計(jì)劃,包括檢查是否有正確的授權(quán)和所需要用到的表、列以及其他引用到的對(duì)象是否存在。
? Execute:這步是真正的由Oracle來(lái)執(zhí)行語(yǔ)句。對(duì)于insert、update、delete操作,這步會(huì)修改數(shù)據(jù),對(duì)于select操作,這步就只是確定選擇的記錄。
? Fetch:返回查詢語(yǔ)句中所獲得的記錄,這步只有select語(yǔ)句會(huì)被執(zhí)行。
COUNT:這個(gè)語(yǔ)句被parse、execute、fetch的次數(shù)。
CPU:這個(gè)語(yǔ)句對(duì)于所有的parse、execute、fetch所消耗的cpu的時(shí)間,以秒為單位。
ELAPSED:這個(gè)語(yǔ)句所有消耗在parse、execute、fetch的總的時(shí)間。
DISK:從磁盤(pán)上的數(shù)據(jù)文件中物理讀取的塊的數(shù)量。一般來(lái)說(shuō)更想知道的是正在從緩存中讀取的數(shù)據(jù)而不是從磁盤(pán)上讀取的數(shù)據(jù)。
QUERY:在一致性讀模式下,所有parse、execute、fetch所獲得的buffer的數(shù)量。一致性模式的buffer是用于給一個(gè)長(zhǎng)時(shí)間運(yùn)行的事務(wù)提供一個(gè)一致性讀的快照,緩存實(shí)際上在頭部存儲(chǔ)了狀態(tài)。
CURRENT:在current模式下所獲得的buffer的數(shù)量。一般在current模式下執(zhí)行insert、update、delete操作都會(huì)獲取buffer。在current模式下如果在高速緩存區(qū)發(fā)現(xiàn)有新的緩存足夠給當(dāng)前的事務(wù)使用,則這些buffer都會(huì)被讀入了緩存區(qū)中。
ROWS: 所有SQL語(yǔ)句返回的記錄數(shù)目,但是不包括子查詢中返回的記錄數(shù)目。對(duì)于select語(yǔ)句,返回記錄是在fetch這步,對(duì)于insert、update、delete操作,返回記錄則是在execute這步。
?
A、query+current/rows 平均每行所需的block數(shù),太大的話(超過(guò)20)SQL語(yǔ)句效率太低
B、Parse count/Execute count parse count應(yīng)盡量接近1,如果太高的話,SQL會(huì)進(jìn)行不必要的reparse
C、rows Fetch/Fetch Fetch Array的大小,太小的話就沒(méi)有充分利用批量Fetch的功能,增加了數(shù)據(jù)在客戶端和服務(wù)器之間的往返次數(shù)。
D、disk/query+current 磁盤(pán)IO所占邏輯IO的比例,太大的話有可能是db_buffer_size過(guò)小(也跟SQL的具體特性有關(guān))
E、elapsed/cpu 太大表示執(zhí)行過(guò)程中花費(fèi)了大量的時(shí)間等待某種資源
F、cpu Or elapsed 太大表示執(zhí)行時(shí)間過(guò)長(zhǎng),或消耗了了大量的CPU時(shí)間,應(yīng)該考慮優(yōu)化
G、執(zhí)行計(jì)劃中的Rows 表示在該處理階段所訪問(wèn)的行數(shù),要盡量減少
B、Parse count/Execute count parse count應(yīng)盡量接近1,如果太高的話,SQL會(huì)進(jìn)行不必要的reparse
C、rows Fetch/Fetch Fetch Array的大小,太小的話就沒(méi)有充分利用批量Fetch的功能,增加了數(shù)據(jù)在客戶端和服務(wù)器之間的往返次數(shù)。
D、disk/query+current 磁盤(pán)IO所占邏輯IO的比例,太大的話有可能是db_buffer_size過(guò)小(也跟SQL的具體特性有關(guān))
E、elapsed/cpu 太大表示執(zhí)行過(guò)程中花費(fèi)了大量的時(shí)間等待某種資源
F、cpu Or elapsed 太大表示執(zhí)行時(shí)間過(guò)長(zhǎng),或消耗了了大量的CPU時(shí)間,應(yīng)該考慮優(yōu)化
G、執(zhí)行計(jì)劃中的Rows 表示在該處理階段所訪問(wèn)的行數(shù),要盡量減少
?
EG:
?
alter session set max_dump_file_size=unlimited;
alter session set timed_statistics=true;
alter session set events '10046 trace name context forever, level 12';
select 'Hello, world; today is '||sysdate from dual; exit;
alter session set timed_statistics=true;
alter session set events '10046 trace name context forever, level 12';
select 'Hello, world; today is '||sysdate from dual; exit;
?
tkprof card_ora_13226.trc trace.txt print=100 record=sql.txt sys=no
?
然后查詢trace.txt就是分析內(nèi)容了
?
?