在生产环境中,可能会存在各种潜在的sql问题,比如由于硬件资源导致,如果影响到了IO,CPU,就会导致一些本来运行很快的sql语句变慢或者系统响应严重减缓。
比如由于数据库的一些设置导致执行计划的问题,sql_profile导致的执行计划稳定带来的性能不稳定,表中统计信息的变更导致的执行计划的变化等等。
有时候等到问题发生的时候,可能已经发生较长的一段时间了。如果想一下子定位问题还是很困难的,在sql_id没有发生变化的情况下,如果要查看语句的执行频率,一种可能就是通过在awr中筛查,但是可行性太差。毕竟耗时费力,还不灵活,很有可能问题sql的执行时间再特定的几个时间段内,那么完整的抽取也就有些冗余了,针对性不强。这个时候可以使用脚本来抽取DBA_HIST_SQLSTAT的信息,然后结合快照信息,得到一个快照级的sql语句执行情况。
shell脚本的内容如下:
sqlplus -s $DB_CONN_STR@$SH_DB_SID
set linesize 200
col BEGIN_INTERVAL_TIME format a30
set pages 50
select * from (
select
BEGIN_INTERVAL_TIME,
SQL_ID,
sum(CPU_TIME_DELTA),
sum(DISK_READS_DELTA),
sum(Executions_total),
sum(EXECUTIONS_DELTA),
count(*)
from
DBA_HIST_SQLSTAT a, dba_hist_snapshot s
where
s.snap_id = a.snap_id
and to_char(s.begin_interval_time,'yyyymmdd')='$3'
and EXTRACT(HOUR FROM S.END_INTERVAL_TIME) between $1 and $2
and sql_id='$4'
group by
SQL_ID,
executions_total,
EXECUTIONS_DELTA,
BEGIN_INTERVAL_TIME
order by
sum(CPU_TIME_DELTA) desc)
where rownum
exit
EOF
执行脚本的情况如下:
我们想查看在2014年11月9号的1点到22点之间,sql_id 7sx5p1ug5ag12的执行频率,得到的结果如下:
ksh showsqlhist.sh 1 22 20141109 7sx5p1ug5ag12
BEGIN_INTERVAL_TIME SQL_ID SUM(CPU_TIME_DELTA) SUM(DISK_READS_DELTA) SUM(EXECUTIONS_TOTAL) SUM(EXECUTIONS_DELTA) COUNT(*)
------------------------------ ------------- ------------------- --------------------- --------------------- --------------------- ----------
09-NOV-14 05.00.39.436 AM 7sx5p1ug5ag12 1071833 0 59785 11712 1
09-NOV-14 12.00.25.211 AM 7sx5p1ug5ag12 1040858 0 48075 12052 1
可以简单的验证一下。比如我们想查看12:00左右的时候sql_id 7sx5p1ug5ag12 的执行情况。来得到一个awr报告。
Executions | Rows Processed | Rows per Exec | Elapsed Time (s) | %CPU | %IO | SQL Id | SQL Module | SQL Text |
---|---|---|---|---|---|---|---|---|
12,052 | 12,052 | 1.00 | 1.03 | 101.5 | 0 | 7sx5p1ug5ag12 | DBMS_SCHEDULER | SELECT SPARE4 FROM SYS.OPTSTAT... |
或者来反证,可能绝大多数时候发现问题的时候,我们会生成awr报告,如果看到某些sql语句可能存在问题,可以使用脚本得到一个语句的执行频率,结合快照来看更加具有针对性。
对于排查问题来说还是有一定的帮助的。