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