今天在巡检数据时发现,日志报临时表空间不足,因为平时临时表空间使用率很低,今天竟然不够用了,随机取数据库AWR报告进行分析,发现异常等待事件,具体信息如下:
http://s7/mw690/001N2SGigy6ElSmYkEm16&690path read temp" TITLE="AWR实战分析之----direct path read temp" />
从DB
Time上看,数据库负载有一点点偏大,因为是在业务高峰时期,还算可以,继续看等待事件
http://s10/mw690/001N2SGigy6ElSn2jvHd9&690path read temp" TITLE="AWR实战分析之----direct path read temp" />
说实施这两个等待事件第一次在生产库上遇到,先说说产生的原理:
1.大量的磁盘排序操作,order by, group by, union,
distinct, rollup,max() 无法在PGA中完成排序,
需要利用temp表空间进行排序,当从临时表空间中读取排序结果时,会产生direct path read.
2. 大量的Hash
Join操作,利用temp表空间保存hash区。
3. SQL语句的并行处理
4.
大表的全表扫描,在10g开始,全表扫描的算法有新的变化,根据表的大小、高速缓存的大小等信息,决
定是否绕过SGA直接从磁盘读Oracle11g取数据。而10g则是全部通过高速缓存读取数据,称为table
scan
(large)。11g认为大表全表时使用直接路径读,可能比10g中的数据文件散列读(db file
scattered
reads)速度更快,使用的latch也更少。
原理清楚了,定位SQL其实很简单,有以下两种情况:
第一种:当时发现,可以通过以下方法进行定位
select sql_id,count(*) from v$session where
event= 'direct
path read temp' group by sql_id desc;
重点关注count(*)值较高的SQL
第二种:很久以后才发现,可以通过以下方法进行定位
select sql_id,count(*) from
dba_hist_active_sess_history where event= 'direct path read
temp' group by sql_id
desc;
其实前面原理说了四条,基本上可以这么理解,出现这种情况,基本上可以定位在以下两个方面
1.SQL执行计划不是最优,需要进行优化
2.SQL写法欠佳,需要进行改写
那么看看我生产库上的SQL是什么
select l.*
from T_APPROVE_LOG l, t_wfext_activity wa
where l.processdefid = wa.processdefid
and l.prevactdefid = wa.actdefid
and wa.activitytype = 0
and l.workflowid in
(select ap.workflowid
from t_approve_process ap
where ap.requester =
(select t.requester
from t_approve_process t
where t.workflowid =
(select max(p.workflowid)
from t_approve_process p
where p.parentworkflowid = :1)))
写法上不是最优这是肯定的,那么我们来对比一下运用sql_profile文件优化后的SQL报告计划对比情况:
http://s8/mw690/001N2SGigy6ElU1ZdR577&690path read temp" TITLE="AWR实战分析之----direct path read temp" />
优化前后效果很明显,因为用的是sql_profile文件进行优化,本想从sql_profile中的执行计划进行反推看看添加那些hint进行优化,最终没有试出来,有空仔细研究下sql_profile内部工作原理,成功后再和大家分享,今天到此为止,技术交流可以QQ我,谢谢!
加载中,请稍候......