察看执行计划和sql跟踪工具之TKPROF

======================================================================================
TKPROF:将底层的跟踪文件转换成易懂的格式。

       这东西无须安装,关键是如何启用它。

        启用:

        alter session set timed_statistics=true;

        alter session set events '10046 trace name context forever, level 12';

        然后再执行你需要执行的SQL

        获取跟踪文件名

        select rtrim(c.value,'/')||'/'||d.instance_name||'_ora_'||ltrim(to_char(a.spid))||'.trc'

        from v$process a, v$session b, v$parameter c, v$instance d

        where a.addr=b.paddr

        and    b.audsid=sys_context('userenv','sessionid')

        and    c.name='user_dump_dest'

        生成tkprof报告

        tkprof /usr/...........................xxxx.trc tkprof.prf

        查看分析报告

        首先,“查找”找到你执行那个SQL。后面列出大致如下内容。

        call     count       cpu    elapsed       disk      query    current        rows

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

Parse        1      0.07       0.08          0          0          0           0

Execute      1      0.00       0.00          0          0          0           0

Fetch        2      2.32       3.05        187      44994          0           1

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

total        4      2.40       3.14        187      44994          0           1

 

以及下面的内容,这是等待事件,非常有用。

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

  db file sequential read                       187        0.06          0.56

  SQL*Net message from client                     2        0.00          0.00

=======================================================================================

Tkprof: 分析ORACLE跟踪文件并且产生一个更加人性化清晰的输出结果的可执行工具

使用步骤:
SQL> alter system set  timed_statistics=true;
1.用户级自跟踪:
ALTER SESSION SET SQL_TRACE=TRUE;---开始跟踪
这期间的sql都会被记录到udump下的Trace中
ALTER SESSION SET SQL_TRACE=FALSE;---结束跟踪

2.用户级DBA跟踪:
SQL>exec sys.dbms_system.set_sql_trace_in_session(sid,serial#,true);---开始跟踪

这期间的sql都会被记录到udump下的Trace中

SQL>exec sys.dbms_system.set_sql_trace_in_session(sid,serial#,false);---结束跟踪

现只对body中的每部分作出详细说明:

  1) sql语句的统计信息

  我们把select语句的执行过程分成3个阶段(分析 执行 取结果),把DML语句的执行分成2个阶段(分析 执行)。格式化的输出文件中列出了sql语句执行的每一阶段所耗费资源统计信息,对于这些信息,是以行列的模式给出的。每一行代表每个sql执行中的具体某一阶段所耗费的相应资源。这样通过分析每个阶段耗费的资源,可以知道哪个sql有问题,并进一步知道该sql执行过程中哪一阶段出现了问题,从而快速定位问题,进而迅速解决问题。

  下面对每个列进行说明:

  call : 表示sql语句执行的每个阶段,每个sql语句的活动被分成以下3部分:

  Parse: 语句被解析的次数,主要是生成执行计划。包含hard parse与soft parse。

  需要做的工作:权限检查,表、列、引用的表的存在性检查;比较执行计划,选出最好的一个等等。

  Execute: 真正执行语句的时间,对于DML语句,在此阶段中修改数据;对于select语句,这步只是标识出查询出的行。

  Fetch : 只对select语句有效,DML语句的执行并没有该阶段

  其它列的值都是与sql执行三个阶段中所耗费的资源的统计值

  COUNT

  一个语句被parsed、executed、fetched的次数

  CPU

  执行这个语句的每个阶段耗费的cpu时间

  ELAPSED

  执行这个语句的每个阶段耗费的总时间(包括上面的cpu时间与其它时间,如读数据)

  DISK

  每个阶段读硬盘的次数(有可能从file system buffer中取得数据)。对于该参数,我们希望该值越小越好,如果该值很大,该sql需要调整,建立相关索引或看是否正确的使用了索引

  QUERY

  每个阶段以consistent mode 方式从数据库buffer中查询的buffers数。对于查询,其buffer一般都是以consistent mode模式被读取

CURRENT

  每个阶段以current mode方式从数据库buffer中查询的buffers数。Buffers are often。对于DML语句,需要的buffer是以current mode模式被读取的。

  QUERY + CURRENT 的和是该sql语句总的存取的buffer数目

  ROWS

  这个sql语句最后处理的行数,不包括子查询中查询出来的行数。

  对于select语句,该值产生于fetch阶段;对于dml该值产生于execute阶段。

  因为统计耗费的时间时,最小的计量单位为0.01秒,所以如果得到一个阶段中耗费的时间为0,并不表示这个阶段没有耗费时间,而是极可能说明这个阶段耗费的时间小于0.01秒,小于计量单位,数据库无法计时,只要以0.00表示

  2) 与执行计划有关的内容

  Misses in library cache during parse: 1 -- 说明hard parse的次数

  Optimizer goal: CHOOSE -- 采用的优化器
  Parsing user id: 19 (SCOTT) -- 那个用户执行的该sql
  Rows Row Source Operation
  ------- ---------------------------------------------------
  12 TABLE ACCESS FULL EMP
  Rows Execution Plan -- 下面是真正的执行计划
  ------- ---------------------------------------------------
  0 SELECT STATEMENT GOAL: CHOOSE
  12 TABLE ACCESS (FULL) OF 'EMP'


  Misses in library cache during parse: 这个统计值是一个比较重要的指标,如果该值与该语句的parse统计值基本相等,并且该值比较大,而且该sql的parse阶段耗费的资源比较多,则说明你的语句应该采用bind variable模式。

  执行计划部分也比较重要,它能看出查询是否用了索引,和各种关联操作所采用的方法。

  建议用autotrace进行跟踪而不是用上面方法进行跟踪的原因:

  虽然上面的方法给出了sql语句的执行计划、统计数据等信息,但是因为tkprof的格式化输出不给出详尽的costs与statistics信息,这使我们在利用格式化输出判断系统到底是使用基于代价的优化方法还是基于规则的优化方法时,感到很迷茫,我们不能明确的知道到底系统在使用那种优化器。

  但是仅仅因为这个原因就使我们放弃上面跟踪方法而该用autotrace功能是不够的,因为:

  1) 到底系统是使用基于规则的还是基于代价的优化器我们可以借助与其它信息来识别,而且从10G以后,oracle就宣布不再使用基于规则的优化器了。

  2) 上面的跟踪办法能实现autotrace不能完成的功能,因为autotrace只能跟踪本会话,而不能跟踪其它会话,这样假如有一个正在运行的程序出现了性能问题,我们就不能使用autrace去跟踪sql的执行情况。
下面以一个具体的例子的数据说明如何利用格式化的输出文件进行sql的调整:

  第一步: - 现看格式化输出文件最后部分,即汇总部分

===========================================================
OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
| call | count | cpu | elapsed | disk | query | current | rows |
|--------- |------- |------ |--------- |--------- |-------- |--------- |-------- |
| Parse | [A] 7 | 1.87 | 4.53 | 385 | [G] 553 | 22 | 0 |
| Execute | [E] 7 | 0.03 | 0.11 | [P] 0 | [C] 0 | [D] 0 | [F] 0 |
| Fetch | [E] 6 | 1.39 | 4.21 | [P] 182 | [C] 820 | [D] 3 | [F] 20 | 
--------------------------------------------------------------------------
Misses in library cache during parse: 5
Misses in library cache during execute: 1
8 user SQL statements in session.
12 internal SQL statements in session.
[B] 54 SQL statements in session.
3 statements EXPLAINed in this session.
 


  (1). 通过比较 [A] 与 [B],我们可以发现是否有过量的parsing现象。在上面的例子中,我们可以看到在session中执行了54个语句,但是只有7次parses,所以这是比较正常的,没有过量的parse现象。

  (2). 利用 [P], [C] & [D] 来决定数据库高速缓存的命中率问题

Hit Ratio is logical reads/physical reads:
Logical Reads = Consistent Gets + DB Block Gets
Logical Reads = query + current
Logical Reads = Sum[C] + Sum[D]
Logical Reads = 0+820 + 0+3
Logical Reads = 820 + 3
Logical Reads = 823
Hit Ratio = 1 - (Physical Reads / Logical Reads)
Hit Ratio = 1 - (Sum[P] / Logical Reads)
Hit Ratio = 1 - (128 / 823)
Hit Ratio = 1 - (0.16)
Hit Ratio = 0.84 or 84% 


  (3). 我们希望fetch的次数要比rows小,即一次fetch可以取多行数据(array fetching),我们可以更高效的取得查询数据。

  这可以通过比较[E]与[F].

  [E] = 6 = Number of Fetches

  [F] = 20 = Number of Rows

问题判断:
1. query+current/rows 平均每行所需的block数,太大的话(超过20)SQL语句效率太低
2. Parse count/Execute count parse count应尽量接近1,如果太高的话,SQL会进行不必要的reparse。
要检查Pro*C程序的MAXOPENCURSORS是不是太低了,或不适当的使用的RELEASE_CURSOR选项
3. rows Fetch/Fetch Fetch Array的大小,太小的话就没有充分利用批量Fetch的功能,
增加了数据在客户端和服务器之间的往返次数。在Pro*C中可以用prefetch=NN,Java/JDBC中可调用SETROWPREFETCH,
在PL/SQL中可以用BULK COLLECT,SQLPLUS中的arraysize(缺省是15)  
4. disk/query+current 磁盘IO所占逻辑IO的比例,太大的话有可能是db_buffer_size过小(也跟SQL的具体特性有关)  
5. elapsed/cpu 太大表示执行过程中花费了大量的时间等待某种资源  
6. cpu OR elapsed 太大表示执行时间过长,或消耗了大量的CPU时间,应该考虑优化

举例:

1.用户级DBA跟踪:
SQL> select distinct sid from v$mystat;

       SID
----------
       153

SQL> select sid, serial# from v$session
  2  where sid=153;

       SID    SERIAL#
---------- ----------
       153        128

SQL> alter system set  timed_statistics=true;

系统已更改。

SQL> exec sys.dbms_system.set_sql_trace_in_session(153,128,true);

PL/SQL 过程已成功完成。

SQL> select count(*) from dba_users;

  COUNT(*)
----------
        22
这期间的sql会记录到udump下的Trace中

SQL> exec sys.dbms_system.set_sql_trace_in_session(153,128,false);

PL/SQL 过程已成功完成。
------结束跟踪

2.用户级自跟踪:

SQL> ALTER SESSION SET SQL_TRACE=TRUE;

会话已更改。

SQL> select count(*) from dba_users;

  COUNT(*)
----------
        22
这期间的sql会记录到udump下的Trace中


SQL> ALTER SESSION SET SQL_TRACE=false;

会话已更改。
------结束跟踪

使用 TKPROF格式化跟踪文件
$ tkprof tracefile.trc output.txt [options]


C:\Users\hp>tkprof F:\oracle\product\10.2.0\db_2\admin\orcl\udump\orcl_ora_1000.trc  d:\output.txt

TKPROF: Release 10.2.0.3.0 - Production on 星期五 8月 15 11:15:01 2008

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


你可能感兴趣的:(数据库,执行计划,休闲,tkprof,sql跟踪)