--使用 tpkrof 输出文件的步骤:
1、show parameter timed_statistics
2、alter session set timed_statistics=true
3、alter session set sql_trace=true
4、--需要分析的sql语句
select owner,count(*)
from all_objects
group by owner;
5、--这个是查询出本次会话的 id
select a.spid
from v$process a,v$session b
where a.addr=b.paddr and
b.audsid=userenv('sessionid')
6、进入 cmd (dos操作屏) (tpkrof 、 exp 、 imp 都是oracle的一些工具)
--执行
tkprof dbase_ora_956.trc report_956.txt
--执行后,trc文件目录下会生成这个 txt 文件,这个会话中 执行过的 sql 语句都有分析在里面。
--也可以指定路径,将这个txt文件生成到哪里。
(注意:sql*plus 从新打开一次就从新开始了一个会话)
--生成了以下信息
--***************start
select owner,count(*)
from all_objects
group by owner
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.03 0.42 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 3 0.54 0.56 0 140888 0 27
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 5 0.57 0.98 0 140888 0 27
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 5
Rows Row Source Operation
------- --------------------------------------------------- 查询方案
27 SORT GROUP BY
29182 FILTER
30212 TABLE ACCESS BY INDEX ROWID OBJ$
30278 NESTED LOOPS
65 TABLE ACCESS FULL USER$
30212 INDEX RANGE SCAN I_OBJ2 (object id 37)
1004 TABLE ACCESS BY INDEX ROWID IND$
1370 INDEX UNIQUE SCAN I_IND1 (object id 39)
1 FIXED TABLE FULL X$KZSPR
1 FIXED TABLE FULL X$KZSPR
1 FIXED TABLE FULL X$KZSPR
1 FIXED TABLE FULL X$KZSPR
1 FIXED TABLE FULL X$KZSPR
1 FIXED TABLE FULL X$KZSPR
1 FIXED TABLE FULL X$KZSPR
1 FIXED TABLE FULL X$KZSPR
1 FIXED TABLE FULL X$KZSPR
--***************end
--分析以上内容:
--parse阶段:这一阶段oracle在共享池(软分析)中查找该查询,并为它创建一个新的计划(硬分析)。
--execute阶段:oracle完成查询的open或execute工作,对于select来说,此阶段将有很多次为空;对于update来说,所有的工作都在此阶段完成。
--fetch阶段:对于select来说,大部分的工作在此阶段完成并可见,但像update那样的语句将显示没有任何工作(不用从update进行fetch)
--列标题:
--call:是parse、execute、fetch、total之一,仅表示正在查看的查询处于哪个阶段。
--count:事件出现多少次,它是一个很重要的数。下面将查看如何解释这个值。
--cpu:按cpu秒计算,这阶段执行查询要花多长的时间。若 TIMED_STATISTICS,则将其增值。
--elapsed:执行此查询要花多长时间。若启用 TIMED_STATISTICS,则将其增值。
--disk:执行查询时需要多少次对磁盘的物理 I/O.
--query:在一致读模式下要处理多少块,它包括从回滚段读的块数。
--current:在current模式下要读多少块。。。。
--rows:多少行受那个处理阶段的影响。select将在fetch阶段显示它们。update将在execute阶段显示多少行受到影响。
--怎么根据这些数据去分析性能;
--1、在执行数大于1时,一个高的(接近100%)分析数与执行数之比---在此用分析语句的次数除以执行语句的次数。
-- 若比值为1,则每次执行这个查询就分析它,这个需要修正。
-- 我们希望该比值接近于0,理想情况下,分析数为1,而执行数远大于1。
-- 如果看到一个大的分析数,则意味着对这个查询执行了很多次软分析。这样急剧地降低了可伸缩性。
-- 应该保证,每次会话中查询只分析了一次,并重复执行它。
--2、在cpu时间与经过的时间之间的大差异---这意味着花了大量的时间等待某些事情。
-- 如果花了一个cpu秒来执行,但它要求10秒壁钟指示的时间,意味着花了90%的运行时间等待一个资源。
--3、较长的cpu或经过时间---这表示最容易得到的查询(意味着不好的查询,降低了性能)。
-- 如果能使它们运行更快,则应用程序将运行更快。
--4、一个高的(fetch count)/ 所获得行数 比,---在此取fetch调用之数与获得行数。
-- 如果这个数接近1,且行数远大于1,则应用程序不执行大批量取数操作。 (最好执行大批量的取数操作)
-- 每种语言api有能力完成这个功能,即一次取得多行。如果没有利用这个功能进行批量取,将花费多得多的时间在客户端与服务器之间
-- 来回往返,这个过多的来回转换除了产生很拥挤的网络状况之外,比一次调用获得很多行要慢得多。
--5、非常的大的磁盘数---这很难估计。
--6、一个非常大的查询或当前计数。---这说明查询做了大量的工作,这是否是一个问题是很主观的。有些查询碰到了大量的数据,这个数就会很大啊。
--分析一下部分:
Misses in library cache during parse: 1
--这边告诉我们,我们执行的查询在共享池中有没有找到,
--如果在这个分析期间在库缓存上没有产生一个错误(即为 0),这说明执行了一个查询的软分析。
--在查询一开始执行时,我们希望这个数为1,若几乎每个查询都为1,则说明没有使用绑定变量(且要对此进行修复),不用重用sql。
Optimizer goal: CHOOSE
--这个告诉我们,这个查询执行期间使用了优化器模式,所开发和使用的查询方案受此设置影响。
Parsing user id: 5
--给出了用于分析查询的 userid。通过下面的语句,可以查询出username
select * from all_users where user_id=5
--tkprof 报表的最后部分为查询方案。