SQL Trace和TKPROF的使用 入门篇

    技术2022-06-11  52

    SQL*Trace(等同于10046 event)是用来产生一个trace统计报告的方法,通过使用SQL_Trace我们可以将一个session时期运行时期的所以统计生成到一个trc文件里,通过tkprof我们可以将这个trc文件格式化成一种report形式的输出,使我们更容易看这个report,SQL Trace通常可以用来看一个对有问题的sql语句进行跟踪,对一些错误也可以进行跟踪。

    下面列举两例来说说他的用法

    例子1,解决drop user的问题。

    在一次使用em的过程中,由于我的错误判断,造成repository不能drop。

    运行emca -deconfig dbcontrol db -repos drop失败,

    打开相关的log文件检查,发现其中drop user MGMT_VIEW cascade这个语句执行的时候报错

    报错如下

    ORA - 00604 :  error occurred at recursive SQL level 1ORA - 00942 :  table  or  view does not exist  .

    这里出现recursive sql表示这句sql在执行的时候还执行了其他的语句了的。

    这个情况使用sql trace就可以看到sql运行是的调用了,

    使用命令alter session set SQL_TRACE=true 即可打开开关。也可以使用alter system set  SQL_TRACE=true这个将对所有的session有效,所以会影响到性能。也可以DBMS_Session.set_sql_trace(true)或者DBMS_SYSTEM.set_sql_trace_in_session(123, 1103, true);

    然后执行你需要监控的语句

    drop user MGMT_VIEW cascade;

    等sql执行完,

    执行

    alter session set SQL_TRACE=false

    停止监控。

    运行命令

    tkprof  ora9i_ora_140.trc drop-analysis

    查看report

    发现再执行这个drop的时候,oracle回去更新一些数据字典里的数据。而其中一个相关的table已经没有了,所以出错,知道原因了,在metalink上查找相关表的信息,从而找到解决问题的方法。

    例子2. 对sql进行监控

    使用以上的方法

    不同的是,tkprof XXXXXXXX explain=user/pwd, 使用执行计划

    得到report找到可疑的那点

    select recordstatus,categoryid,rcordlevel from record_detail a,category b where b.id=a.categoryid and id= 20030700400141 and recordstatus>0

    call count cpu elapsed disk query current rows

    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        1      0.70       0.69          0     225814          0           5

    ——- ——  ——– ———- ———- ———- ———-  ———-

    total        3      0.70       0.69          0     225814          0        ********************************************************************************

    这个可疑的225814让我很生疑。是用id去进行读取的,却有这么高的query

    如果有类似经验的用户应该可以知道怎么回事了

    让我们继续往下看

    Rows     Row Source Operation

    ……….

    接下来真相大白了

    Misses in library cache during

    parse: 1

    Optimizer goal: CHOOSE

    Parsing user id: 41

    Rows Row Source Operation

    ——- —————————————————

    0 ‘TABLE ACCESS FULL  RECORD_DETAIL’

    1 INDEX RANGE SCAN (object id 3080) ********************************************************************************

    这里有一个全表扫描

    接着分析表的结构和index

    SQL> select index_name,table_name,column_name from user_ind_columns 2 where table_name=upper(’record_detail’);

    INDEX_NAME TABLE_NAME COLUMN_NAME

    —————————— —————————— ——————–

    IDX_RECORDID RECORD_DETAIL ID

    SQL>desc record_detail

    在record_detail的id建有index,但是根据表结构看到id是一个varchar2字段,字符型的字段,而查询时使用的是number类型,Oracle发生隐性的数据类型转换,对应Oracle来说有效的使用index是不能改变值的,而这里也将index失效。

    在查询加上‘’,问题解决。

    修改后,在sql trace检查,query降低为10,相比之下,相差太远。

    当然这些问题都可以通过别的方法进行分析,不过在这里是通过这样的简单例子,让我们对sql trace有个基本上的了解而已。

    SQL trace是性能监控和问题排查相当实用的工具,同时也是一个使用上非常有深度的工具,要熟练运用,我们还通过大量的实例的学习和不断的总结才能将起发挥的很有力。

    如果没有那句“三十而立”,三十岁的男人正可以轻轻松松专业论坛 http://www.inthirties.com技术博客 http://blog.csdn.net/inthirties个人站点 http://blog.inthirties.comOracle Mysql技术论坛| 打造实用的Oracle Mysql技术交流园地

     

     

     

    http://blog.csdn.net/inthirties/archive/2009/05/10/4162961.aspx


    最新回复(0)