首先我们要登录到sqlplus上
SQL>sqlplus scott/tiger
为了方便查找跟踪文件我们在跟踪文件后面加上后缀'look_for_me',也可以不加,我们下面的例子也没有加。
SQL>alter session set tracefile_identifier='look_for_me';
第一步查看跟踪文件的路径和文件名
SQL>show parameter user_dump_dest;-- 跟踪文件的路径
SQL> select c.value || '/' || d.instance_name || '_ora_' || 2 a.spid || '.trc' || 3 case when e.value is not null then '_'||e.value end trace 4 from v$process a, v$session b, v$parameter c, v$instance d, v$parameter e 5 where a.addr = b.paddr 6 and b.audsid = userenv('sessionid') 7 and c.name = 'user_dump_dest' 8 and e.name = 'tracefile_identifier' 9 / TRACE -------------------------------------------------------------------------------- e:\app\user\diag\rdbms\orcl\orcl\trace/orcl_ora_5240.trc
在之前版本中,我们需要访问以上几张V视图才可以得到某一个sid的trace file的绝对路径。在11g中,Oracle为我们新增了一个视图 V$DIAG_INFO。
SQL>select * from v$diag_info;
INST_ID NAME VALUE ---------- ---------------------------------------------------------------- ----------------------------------------------------------- 1 Diag Enabled TRUE 1 ADR Base e:\app\user 1 ADR Home e:\app\user\diag\rdbms\orcl\orcl 1 Diag Trace e:\app\user\diag\rdbms\orcl\orcl\trace 1 Diag Alert e:\app\user\diag\rdbms\orcl\orcl\alert 1 Diag Incident e:\app\user\diag\rdbms\orcl\orcl\incident 1 Diag Cdump e:\app\user\diag\rdbms\orcl\orcl\cdump 1 Health Monitor e:\app\user\diag\rdbms\orcl\orcl\hm 1 Default Trace File e:\app\user\diag\rdbms\orcl\orcl\trace\orcl_ora_5240.trc
V$DIAG_INFO 视图列出了所有重要的ADR 位置:
(1) ADR Base:ADR 基目录的路径
(2) ADR Home:当前数据库实例的ADR 主目录的路径
(3) Diag Trace:文本预警日志和后台/前台进程跟踪文件的位置
(4) Diag Alert:XML 版本的预警日志的位置
(5) …
(6) Default Trace File:会话的跟踪文件的路径。SQL 跟踪文件将写入到这里。也是我们需要的路径。
至于以上各个位置的文件的具体作用这里我们不是重点,就不在描述。
通过查询我们可以看到通过以上两种方法我们查询到的跟踪文件是一样的
e:\app\user\diag\rdbms\orcl\orcl\trace\orcl_ora_5240.trc
第二步打开SQL_TRACE
SQL>alter session set sql_trace=true;
第三步执行查询
SQL>select * from emp,dept where emp.deptno=dept.deptno;
第四步关闭sql_trace
SQL>alter session set sql_trace=false;
然后退出sqlplus
第五步 切换到我们查询到的跟踪文件目录 执行
E:\app\User\diag\rdbms\orcl\orcl\trace>tkprof orcl_ora_5240.trc 5240.txt
这时我们打开2708.txt 可以看到输出
select * from emp,dept where emp.deptno=dept.deptno call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 0.00 0.00 0 11 0 14 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 0.00 0.00 0 11 0 14
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格式化的文件很容易看出需要调整的SQL语句。查找的依据是:
*耗费大量的CPU资源
*花费较长的时间进行SQL分析、执行和获取
*从磁盘读大量的数据块,而从SGA区读的数据很少
*访问大量的数据块但只返回一点数据
一旦找到这些语句就可以用执行计划工具来进一步决定为什么这些语句性能这么低了。