一. SQL_TRACE

  当SQL语句出现性能问题时,我们可以用SQL_TRACE来跟踪SQL的执行情况,通过跟踪,我们可以了解一条SQL或者PL/SQL包的运行情况,SQL_TRACE命令会将SQL执行的整个过程输出到一个trace文件中,我们可以读这个trace 文件来了解在这个SQL执行过程中Oracle 都做了哪些操作:

a.SQL是如何操作数据的。
b.SQL执行过程中产生了那些等待时间。
c.SQL执行中消耗了多少资源。
d.SQL的实际执行计划。
e.SQL产生的递归语句。

可以通过sql命令启动SQL_TRACE,或者在初始化参数里面。

SQL>alter session set sql_trace=true;

或者

SQL> alter database set sql_trace=true;

  这两条命令的区别:

  在session级别设置,只对当前session进行跟踪,在实例级别,会对实例上所有的SQL做跟踪,这种方式跟踪的SQL太多,代价是非常大的,所有很少用。如果是在初始化文件里面设置,只需要在参数文件里添加一个sql_trace 参数即可。

示例:

1.确定当前的trace文件。

1.1   通过设置trace 文件标识

SQL> alter session set tracefile_identifier='TEST_TRACE';

会话已更改。

  设置标识的目的就是方便我们查找生成的trace文件。我们只需要在trace目录查找文件名里带有标识的文件即可。
在Oracle 10g中,SQL_TRACE生成的trace文件默认路劲是$ORACLE_BASE/admin/SID/udump. 
在Oracle 11g,trace 默认路径在:$ORACLE_BASE/diag/rdbms/orcl/orcl/trace目录下.

1.2直接用如下SQL直接查出,当前的trace文件名。

SELECT      d.VALUE

         || '/'

         || LOWER (RTRIM (i.INSTANCE, CHR (0)))

         || '_ora_'

         || p.spid

         || '.trc'

            AS "trace_file_name"

  FROM   (SELECT   p.spid

            FROM   v$mystat m, v$session s, v$process p

           WHERE   m.statistic# = 1 AND s.SID = m.SID AND p.addr = s.paddr) p,

         (SELECT   t.INSTANCE

            FROM   v$thread t, v$parameter v

           WHERE   v.NAME = 'thread'

                   AND (v.VALUE = 0 OR t.thread# = TO_NUMBER (v.VALUE))) i,

         (SELECT   VALUE

            FROM   v$parameter

           WHERE   NAME = 'user_dump_dest') d;

SQL> SELECT    d.VALUE

  2        || '/'

  3        || LOWER (RTRIM (i.INSTANCE, CHR (0)))

  4        || '_ora_'

  5        || p.spid

  6        || '.trc' as "trace_file_name"

  7    FROM (SELECT p.spid

  8            FROM v$mystat m, v$session s, v$process p

  9          WHERE m.statistic# = 1 AND s.SID = m.SID AND p.addr = s.paddr) p,

 10        (SELECT t.INSTANCE

 11            FROM v$thread t, v$parameter v

 12          WHERE v.NAME = 'thread'

 13            AND (v.VALUE = 0 OR t.thread# = TO_NUMBER (v.VALUE))) i,

 14        (SELECT VALUE

 15            FROM v$parameter

 16          WHERE NAME = 'user_dump_dest') d;

trace_file_name

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

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

查义当前Trace文件

2.启动SQL_TRACE

SQL> alter session set sql_trace=true;

会话已更改。

3.进行相关事务操作

SQL> select * from t;

4.关闭SQL_TRACE

SQL> alter session set sql_trace=false;

会话已更改。

注意,这里是显示的关闭SQL_TRACE,在session级别,也可以直接退出SQLPLUS来终止SQL_TRACE。

二. TKPROF的使用简介

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

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

TKPROF 命令语法

filename1  指定的输入文件,可以是多个文件联起来。
Filename2  格式化输出文件。
SORT     在输出到输出文件前,先进程排序。如果省去,则按照实际使用的顺序输出到文件中。排序选项有以下多种:

  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

SORT选项

PRINT        只列出输出文件的第一个integer 的SQL语句。默认为所有的SQL语句。
AGGREGATE    如果= NO ,则不对多个相同的SQL进行汇总。
INSERT       SQL 语句的一种,用于将跟踪文件的统计信息存储到数据库中。在TKPROF创建脚本后,在将结果输入到数据库中。
SYS         禁止或启用 将SYS用户所发布的SQL语句列表到输出文件中。
TABLE       在输出到输出文件前,用于存放临时表的用户名和表名。
EXPLAIN     对每条SQL 语句确定其执行规划。并将执行规划写到输出文件中。
其中比较有用的一个排序选项是fchela,即按照elapsed time fetching来对分析的结果排序(记住要设置初始化参数timed_statistics=true),生成的文件将把最消耗时间的sql放在最前面显示。另外一个有用的参数就是sys,这个参数设置为no可以阻止所有以sys用户执行的sql被显示出来,这样可以减少分析出来的文件的复杂度,便于查看。

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

Tkprof的使用步骤基本上遵循以下几步:
1、设置TIMED_STATISTICS为True,可以在会话级别,也可以在实例级别。

会话级:
SQL> alter session set timed_statistics=True;
实例级:
SQL> alter system set timed_statistics=True scope=both;

设置TIMED_STATISTICS

2、 设置SQL_TRACE,可以在会话级,也可以在数据库级。

会话级:
SQL> alter session set sql_trace=true;
或者:
SQL>EXEC DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(SID,SERIAL#,TRUE);
实例级:
SQL> alter system set sql_trace=true scope=both;

设置SQL_TRACE

下面两个例子说明一下具体的用法:

SQL> create table testlib  as select object_name noindex,object_name idx from dba_objects;

表已创建。

SQL> alter session set timed_statistics=true;

会话已更改。

设置Timed_statistics

SQL> alter session set sql_trace=true;

会话已更改。

SQL> select count(*) from testlib;

  COUNT(*)
----------
69304 SQL> alter session set sql_trace= false; 会话已更改。

用户级跟踪

或DBA跟踪:(例如sys跟踪test,需要用sysdba登录

SQL> select username,sid,serial# from v$session where username='system';
USERNAME SID SERIAL#
------------------------------ ---------- ----------
GDSBDW 37 27544 SQL>exec sys.dbms_system.set_sql_trace_in_session(37,27544,true); SQL>exec sys.dbms_system.set_sql_trace_in_session(37,27544,false);

DBA级跟踪

3.查询跟踪文件位置:

SQL> select 'dss_ora_'||spid||'.trc' from v$process where addr = (select paddr f
rom v$session where sid=37);
'DSS_ORA_'||SPID||'.TRC'
------------------------
orcl_ora_3040.trc

查询跟踪文件位置

也可以用下面的sql语句获得trace文件的所在位置

 SQL>  select
2 d.value||'/'||lower(rtrim(i.instance,chr(0)))||'_ora_'||p.spid||'.trc' trace_file_name
3 from
4 (select p.spid
5 from sys.v$mystat m, sys.v$session s,sys.v$process p
6 where m.statistic#=1 and s.sid=m.sid and p.addr=s.paddr) p,
7 (select
8 t.instance from sys.v$thread t,sys.v$parameter v
9 where v.name ='thread' and (v.value =0 or t.thread#= to_number(v.value))) i,
10* (select value from sys.v$parameter where name ='user_dump_dest') d TRACE_FILE_NAME
--------------------------------------------------------------------------------
f:\app\administrator\diag\rdbms\orcl\orcl\trace/orcl_ora_3040.trc

查询跟踪文件位置

4.使用tkprof分析trace文件

explain=user/password

  在trace文件中输入SQL的执行计划,需要注意的是,如果不使用explain,在trace 文件中我们看到的是SQL实际的执行路劲。 如果使用了explain,tkprof在trace文件中不但输入SQL的实际执行路径,还会生成该SQL的执行计划。

sys=no

  如果设置为yes,在trace 文件中将输入所有的SYS用户的操作,也包含用户SQL语句引发的递归SQL。
  如果为no,则不输出这些信息。
  不过默认情况下是yes,实际上设置为no后,trace文件具有更佳的可读性,因此一般在用tkprof工具时都手工的把该参数设置为no。

aggregate=yes|no

默认情况下,tkprof工具将所有相同的SQL在输入文件中做合并,如果设置为no,则分别列出每个SQL的信息。一般合并后看起来比较简洁,如果需要查看每一个SQL单独的信息,可以把aggregate设置为no。

C:\Documents and Settings\Administrator>tkprof  f:\app\administrator\diag\rdbms\orcl\orcl\trace/orcl_ora_4020.trc   f:\4020.trc.txt  aggregate=yes sys=no waits=yes sort=fchela

Tkprof分析Trace文件

tkprocf输出了以下文件:f:\4020.trc.txt

TKPROF: Release 11.1.0.6.0 - Production on 星期一 3月 29 13:50:42 2010

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

Trace file: f:\4020.trc
Sort options: fchela
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call ******************************************************************************** OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 6 0.01 5403.67 0 1 0 0
Execute 7 0.00 0.00 0 0 0 0
Fetch 8 0.03 0.07 137 2080 0 4
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 21 0.04 5403.75 137 2081 0 4 Misses in library cache during parse: 2
Misses in library cache during execute: 1 OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 2 0.00 0.05 0 0 0 0
Execute 2 0.00 0.01 0 0 0 0
Fetch 2 0.00 0.08 379 67 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6 0.00 0.15 379 67 0 1 Misses in library cache during parse: 2
Misses in library cache during execute: 1 7 user SQL statements in session.
2 internal SQL statements in session.
9 SQL statements in session.
********************************************************************************
Trace file: f:\4020.trc
Trace file compatibility: 11.01.00
Sort options: fchela
1 session in tracefile.
7 user SQL statements in trace file.
2 internal SQL statements in trace file.
9 SQL statements in trace file.
6 unique SQL statements in trace file.
107 lines in trace file.
124 elapsed seconds in trace file.

Tkprof分析Trace文件结果:

5.分析结果关键字解释

PARSING IN CURSOR 部分:
Len: 被解析SQL的长度
Dep: 产生递归SQL的深度
Uid:user id
Otc: Oracle command type 命令的类型
Lid: 私有用户id
Tim:时间戳
Hv: hash value
Ad:SQL address PARSE,EXEC,FETCH 部分
C: 消耗的CPU time
E:elapsed time 操作的用时
P: physical reads 物理读的次数
Cr: consistent reads 一致性方式读取的数据块
Cu:current 方式读取的数据块
Mis:cursor misss in cache 硬分析次数
R: -rows 处理的行数
Dep: depth 递归SQL的深度
Og: optimizer goal 优化器模式
Tim:timestamp时间戳 STATS 部分:
Id: 执行计划的行源号
Cnt:当前行源返回的行数
Pid:当前行源号的父号
Pos:执行计划中的位置
Obj:当前操作的对象id(如果当前行原始一个对象的话)
Op:当前行源的数据访问操作

分析结果及关键字解释

  我们来看刚才生成的trace文件,头部信息描述了tkprof 的版本以及报告中一些列的含义,对于任何一条sql语句,都应该包含Parse—sql分析阶段,Execute—sql执行阶段,Fetch—数据提取阶段,横向的列如图所示,包含消耗cpu时间0.00秒,操作总耗时0.04秒,物理读取了0个数据块,没有发生current方式的读取(一般在update会发生),一共提取记录1条。
Misses in library cache during parse: 2表示这是2次硬分析(表示shared pool 中2次没有命中,软解析为0,硬解析为2)
Misses in library cache during execute: 1表示这是1次硬分析(表示获得了SQL Hander,但是执行时在SQL区没有找到或被覆盖,导致硬解析)
Optimizer mode: ALL_ROWS表示oracle的优化器模式为ALL_ROWS。

  下面是sql执行的具体计划,可以看到执行计划选择的是全表扫描。
经过处理以后的trace文件的确比较容易看明白,它有助于我们分析sql的性能问题。
下面我通过一个trace实例来解释一下,为什么OLTP系统中需要变量绑定机制。
  当用户和数据库建立连接,并发送一条sql语句以后,oracle会对该sql进行hash函数运算(hash算法提供了一种快速存取数据的方法,它用一种算法建立键值与真实值之间的对应关系,每一个真实值只能有一个键值,但是一个键值可以对应多个真实值,以方便存取),得到一个hash值,然后到共享池中寻找是否有匹配的hash值的sql存在;如果有,就直接使用该sql的执行计划去执行sql。如果没有,oracle就会认为这是一条新的sql语句,然后按照语法分析,语义分析,生成执行计划,执行sql这些步骤来执行最终把结果返回给用户。

  这些步骤也被成为硬分析,可以想象,如果减少硬分析,能够大大降低数据库花费在sql解析上的资源开销。

  我们先执行一条sql 1000次,比较绑定变量和不绑定变量的差异。得到结果以后,要计算实际的消耗,我们需要把OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS以及OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS的时间累计起来,前者表示数据字典表的相关的信息,包含权限控制等,后者表示sql所衍生出的递归sql语句的信息。可以看到绑定变量的,整条语句执行时间为0.22+0.02=0.24秒,CPU时间0.18+0.03=0.21秒,分析次数3次,执行次数1003次。而不绑定变量的时候,整条语句执行时间为0.28+1.29=1.57秒,CPU时间0.31+1.26=1.57秒,分析次数1002次,执行次数1003次。可见绑定变量的确能够带来更低的开销。(如何设计数据库中使用绑定变量也是和系统息息相关的,很多数据库问题都是在设计以后就已经存在的)

Oracle 课程八之性能优化之Oracle SQL Trace的更多相关文章

  1. Oracle 课程八之性能优化之10046事件

    Oracle 的事件很多. 具体参考blog: Oracle 跟踪事件 set event 转摘:http://blog.csdn.net/tianlesoftware/archive/2009/12 ...

  2. Oracle 课程八之性能优化之10053事件

    一. 10053事件 当一个SQL出现性能问题的时候,可以使用SQL_TRACE 或者 10046事件来跟踪SQL. 通过生成的trace来了解SQL的执行过程. 我们在查看一条SQL的执行计划的时候 ...

  3. MySQL性能优化(四):SQL优化

    原文:MySQL性能优化(四):SQL优化 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/ ...

  4. 【SQL Server性能优化】运用SQL Server的全文检索来提高模糊匹配的效率

    原文:[SQL Server性能优化]运用SQL Server的全文检索来提高模糊匹配的效率 今天去面试,这个公司的业务需要模糊查询数据,之前他们通过mongodb来存储数据,但他们说会有丢数据的问题 ...

  5. Oracle性能优化之 Oracle里的优化器

    优化器(optimizer)是oracle数据库内置的一个核心子系统.优化器的目的是按照一定的判断原则来得到它认为的目标SQL在当前的情形下的最高效的执行路径,也就是为了得到目标SQL的最佳执行计划. ...

  6. Oracle性能优化之oracle里表、索引、列的统计信息

    一.表的统计信息 表的统计信息用于描述表的详细信息,包括记录数(num_rows).表块的数量(blocks).平均行长度(avg_row_len)等典型维度.这些维度可以通过数据字典表DBA_TAB ...

  7. mysql数据库性能优化(包括SQL,表结构,索引,缓存)

    优化目标减少 IO 次数IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当 ...

  8. MySQL · 性能优化 · MySQL常见SQL错误用法(转自-阿里云云栖社区)

    作者:阿里云云栖社区链接:https://zhuanlan.zhihu.com/p/26043916来源:知乎著作权归作者所有,转载请联系作者获得授权. 前言 MySQL在2016年仍然保持强劲的数据 ...

  9. PLSQL_性能优化工具系列05_SQL Trace/Event 10046 Trace

    2014-06-25 Created By BaoXinjian

随机推荐

  1. JS常见排序算法

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 初学tornado之MVC版helloworld

    作者:the5fire | 标签: MVC  tornado  | 发布:2012-08-06 2:41 p.m. 文接上篇,看我一个简单的helloworld,虽然觉得这个框架着实精小,但是实际开发 ...

  3. SPOJ Lexicographical Substring Search 后缀自动机

    给你一个字符串,然后询问它第k小的factor,坑的地方在于spoj实在是太慢了,要加各种常数优化,字符集如果不压缩一下必t.. #pragma warning(disable:4996) #incl ...

  4. java核心技术记录之java术语

    术语名 缩写 解释 Java Development Kit JDK 编写java程序的程序员使用的软件 Java Runtime Environment JRE 运行java程序的用户使用的软件 S ...

  5. SNAT

    http://blog.chinaunix.net/uid-2628744-id-2454879.html

  6. Python中Lambda, filter, reduce and map 的区别

    Lambda, filter, reduce and map Lambda Operator Some like it, others hate it and many are afraid of t ...

  7. *[hackerrank]Cut the tree

    https://www.hackerrank.com/contests/w2/challenges/cut-the-tree 树分成两部分,求两部分差最小.一开始想多了,后来其实求一下总和,求一下分部 ...

  8. XML DOS 攻击

    内容来自此文:http://msdn.microsoft.com/en-us/magazine/ee335713.aspx DoS(Denial of service:拒绝服务)攻击由来已久(1992 ...

  9. JAVA:23种设计模式详解(转)2

    我们接着讨论设计模式,上篇文章我讲完了5种创建型模式,这章开始,我将讲下7种结构型模式:适配器模式.装饰模式.代理模式.外观模式.桥接模式.组合模式.享元模式.其中对象的适配器模式是各种模式的起源,我 ...

  10. 什么是spring?

    一.对spring的理解. 1.Spring是实现了工厂模式的工厂类(什么是工厂类?简单的来说就是把需要的接口定义到一个类中,需要的时候不用新建,直接从这个类中调用该接口就可以了), 这个类的名字为B ...