使用 Tkprof 分析 ORACLE 跟踪文件

Tkprof是一个用于分析Oracle跟踪文件并且产生一个更加清晰合理的输出结果的可执行工具。如果一个系统的执行效率比较低,一个比较好的方法是通过跟踪用户的会话并且使用Tkprof工具使用排序功能格式化输出,从而找出有问题的SQL语句。


.TKPROF命令语法:
TKPROFfilename1,filename2[SORT=[opion][,option]]
[PRINT=integer]
[AGGREGATE=[YES|NO]]
[INSERT=filename3]
[SYS=[YES|NO]]
[[TABLE=schema.table]|[EXPLAIN=user/password]]
[RECORD=filename]

相关说明:
filename1指定的输入文件,可以是多个文件联起来。
Filename2格式化输出文件。
SORT在输出到输出文件前,先进程排序。如果省去,则按照实际使用的顺序输出到文件中。排序选项有以下多种:
prscntnumberoftimesparsewascalled
prscpucputimeparsing
prselaelapsedtimeparsing
prsdsknumberofdiskreadsduringparse
prsqrynumberofbuffersforconsistentreadduringparse
prscunumberofbuffersforcurrentreadduringparse
prsmisnumberofmissesinlibrarycacheduringparse
execntnumberofexecutewascalled
execpucputimespentexecuting
exeelaelapsedtimeexecuting
exedsknumberofdiskreadsduringexecute
exeqrynumberofbuffersforconsistentreadduringexecute
execunumberofbuffersforcurrentreadduringexecute
exerownumberofrowsprocessedduringexecute
exemisnumberoflibrarycachemissesduringexecute
fchcntnumberoftimesfetchwascalled
fchcpucputimespentfetching
fchelaelapsedtimefetching
fchdsknumberofdiskreadsduringfetch
fchqrynumberofbuffersforconsistentreadduringfetch
fchcunumberofbuffersforcurrentreadduringfetch
fchrownumberofrowsfetched
useriduseridofuserthatparsedthecursor


PRINT只列出输出文件的第一个integerSQL语句。默认为所有的SQL语句。
AGGREGATE如果=NO,则不对多个相同的SQL进行汇总。
INSERTSQL语句的一种,用于将跟踪文件的统计信息存储到数据库中。在TKPROF创建脚本后,在将结果输入到数据库中。
SYS禁止或启用将SYS用户所发布的SQL语句列表到输出文件中。
TABLE在输出到输出文件前,用于存放临时表的用户名和表名。
EXPLAIN对每条SQL语句确定其执行规划。并将执行规划写到输出文件中。

其中比较有用的一个排序选项是fchela,即按照elapsedtimefetching来对分析的结果排序(记住要设置初始化参数timed_statistics=true),生成的文件将把最消耗时间的sql放在最前面显示。另外一个有用的参数就是sys,这个参数设置为no可以阻止所有以sys用户执行的sql被显示出来,这样可以减少分析出来的文件的复杂度,便于查看。


.Tkprof命令输出的解释:


首先解释输出文件中列的含义:
CALL:每次SQL语句的处理都分成三个部分
Parse:这步将SQL语句转换成执行计划,包括检查是否有正确的授权和所需要用到的表、列以及其他引用到的对象是否存在。
Execute这步是真正的由Oracle来执行语句。对于insertupdatedelete操作,这步会修改数据,对于select操作,这步就只是确定选择的记录。
Fetch返回查询语句中所获得的记录,这步只有select语句会被执行。
COUNT:这个语句被parseexecutefetch的次数。
CPU这个语句对于所有的parseexecutefetch所消耗的cpu的时间,以秒为单位。
ELAPSED这个语句所有消耗在parseexecutefetch总的时间。
DISK从磁盘上的数据文件中物理读取的块的数量。一般来说更想知道的是正在从缓存中读取的数据而不是从磁盘上读取的数据。
QUERY在一致性读模式下,所有parseexecutefetch所获得的buffer的数量。一致性模式的buffer是用于给一个长时间运行的事务提供一个一致性读的快照,缓存实际上在头部存储了状态。
CURRENTcurrent模式下所获得的buffer的数量。一般在current模式下执行insertupdatedelete操作都会获取buffer。在current模式下如果在高速缓存区发现有新的缓存足够给当前的事务使用,则这些buffer都会被读入了缓存区中。
ROWS:所有SQL语句返回的记录数目,但是不包括子查询中返回的记录数目。对于select语句,返回记录是在fetch这步,对于insertupdatedelete操作,返回记录则是在execute这步。


.Tkprof的使用步骤基本上遵循以下几步:
1、设置TIMED_STATISTICSTrue,可以在会话级别,也可以在实例级别。
会话级:
SQL>altersessionsettimed_statistics=True;
实例级:
SQL>altersystemsettimed_statistics=Truescope=both;
2、设置SQL_TRACE,可以在会话级,也可以在数据库级。
会话级:
SQL>altersessionsetsql_trace=true
或者:
SQL>EXECDBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(SID,SERIAL#,TRUE);
实例级:
SQL>altersystemsetsql_trace=truescope=both;


四.举例说明:

--启用SQL_TRACE
SQL>altersessionsetsql_trace=true;
会话已更改。
SQL>selectcount(*)frombigtab;

COUNT(*)

----------

1922423

--启用timed_statistics
SQL>altersessionsettimed_statistics=true;

会话已更改。

SQL>selectcount(*)frombigtab;

COUNT(*)

----------

1922423

SQL>altersessionsetsql_trace=false;

会话已更改。


--查询此会话产生的TRACE文件
SQL>selectusername,sid,serial#fromv$sessionwhereusername='SYS';

USERNAMESIDSERIAL#

--------------------------------------------------

SYS192518

SQL>select'orcl_ora_'||spid||'.trc'fromv$processwhereaddr=(selectpaddrfromv$sessionwheresid=19);

'DSS_ORA_'||SPID||'.TRC'

------------------------------------

orcl_ora_7240.trc

也可以通过下面的函数来获取当前的trace文件:

createorreplacefunctiongettracenamereturnvarchar2is
v_resultvarchar2(200);
begin
SELECTd.VALUE
||'/'
||LOWER(RTRIM(i.INSTANCE,CHR(0)))
||'_ora_'
||p.spid
||'.trc'intov_result
FROM(SELECTp.spid
FROMv$mystatm,v$sessions,v$processp
WHEREm.statistic#=1ANDs.SID=m.SIDANDp.addr=s.paddr)p,
(SELECTt.INSTANCE
FROMv$threadt,v$parameterv
WHEREv.NAME='thread'
AND(v.VALUE=0ORt.thread#=TO_NUMBER(v.VALUE)))i,
(SELECTVALUE
FROMv$parameter
WHERENAME='user_dump_dest')d;
returnv_result;
endgettracename;

运行SQL>selectgettracename()fromdual;即可
SQL>selectgettracename()fromdual;

GETTRACENAME()

--------------------------------------------------------------------------

d:/app/administrator/diag/rdbms/orcl/orcl/trace/orcl_ora_7240.trc


--使用tkprof分析trace文件
C:/Users/Administrator.DavidDai>tkprofd:/app/administrator/diag/rdbms/orcl/orcl

/trace/orcl_ora_7240.trcD:/orcl_ora_7240.txtaggregate=yessys=nowaits=yessor

t=fchela

TKPROF:Release11.2.0.1.0-Developmenton星期五52816:48:492010

Copyright(c)1982,2009,Oracleand/oritsaffiliates.Allrightsreserved.


--tkprocf输出了以下文件:D:/orcl_ora_7240.txt

TKPROF:Release11.2.0.1.0-Developmenton星期五52816:48:492010

Copyright(c)1982,2009,Oracleand/oritsaffiliates.Allrightsreserved.

Tracefile:d:/app/administrator/diag/rdbms/orcl/orcl/trace/orcl_ora_7240.trc

Sortoptions:fchela

********************************************************************************

count=numberoftimesOCIprocedurewasexecuted

cpu=cputimeinsecondsexecuting

elapsed=elapsedtimeinsecondsexecuting

disk=numberofphysicalreadsofbuffersfromdisk

query=numberofbuffersgottenforconsistentread

current=numberofbuffersgottenincurrentmode(usuallyforupdate)

rows=numberofrowsprocessedbythefetchorexecutecall

********************************************************************************

OVERALLTOTALSFORALLNON-RECURSIVESTATEMENTS

callcountcpuelapseddiskquerycurrentrows

-----------------------------------------------------------------------

Parse40.000.000000

Execute50.000.000000

Fetch40.797.45570755708202

-----------------------------------------------------------------------

total130.797.45570755708202

Missesinlibrarycacheduringparse:3

Missesinlibrarycacheduringexecute:1

OVERALLTOTALSFORALLRECURSIVESTATEMENTS

callcountcpuelapseddiskquerycurrentrows

-----------------------------------------------------------------------

Parse00.000.000000

Execute00.000.000000

Fetch00.000.000000

-----------------------------------------------------------------------

total00.000.000000

Missesinlibrarycacheduringparse:0

5userSQLstatementsinsession.

0internalSQLstatementsinsession.

5SQLstatementsinsession.

********************************************************************************

Tracefile:d:/app/administrator/diag/rdbms/orcl/orcl/trace/orcl_ora_7240.trc

Tracefilecompatibility:11.1.0.7

Sortoptions:fchela

1sessionintracefile.

5userSQLstatementsintracefile.

0internalSQLstatementsintracefile.

5SQLstatementsintracefile.

5uniqueSQLstatementsintracefile.

73linesintracefile.

75elapsedsecondsintracefile.


.分析会话的示例
先从os上利用top命令找到当前占用cpu资源最高的一个进程的PID号:14483
然后在数据库中根据PID号找到相应的sid号和serial#
SQL>selects.sid,s.serial#fromv$sessions,v$processpwheres.paddr=p.addrandp.spid='14483';
SIDSERIAL#
--------------------
10125695


使用dbms_system.set_sql_trace_in_session包来对这个session进行trace
SQL>execDBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(101,25695,true);
PL/SQLproceduresuccessfullycompleted.


user_dump_dest定义的路径下查找刚刚最近生成的trace文件,可以根据时间来排序,找最近的trace文件,也可以根据SID_ORA_SPID.TRC的规则,即ORCL_ORA_14483.TRC找到TRACE文件。

接着使用tkprof工具对此trace文件进行格式化分析,生成分析后的trace文件。
$tkproforcl_ora_14483.trcallan.txtexplain=system/manageraggregate=yessys=nowaits=yessort=fchela


TKPROF:Release11.2.0.1.0-Developmenton星期五52816:48:492010

Copyright(c)1982,2009,Oracleand/oritsaffiliates.Allrightsreserved.


这里生成的allan.txt文件就是我们最终得到的格式化后的trace文件了,然后打开这个文件进行分析。
最后总的统计:
OVERALLTOTALSFORALLRECURSIVESTATEMENTS
callcountcpuelapseddiskquerycurrentrows
---------------------------------------------------------------------
Parse200.010.0205800
Execute131970.810.9017743663161484
Fetch1294422.8622.1020220594108972
---------------------------------------------------------------------
total2616123.6823.02372213435631610456

<!--EndFragment-->

你可能感兴趣的:(oracle)