大家都知道AWR的中文名叫“自动负载信息库”,英文名叫“Automatic Workload Repository”。它是通过对比两次快照收集到的统计信息,来生成报表数据。
这里只说一说SQL ordered by Elapsed Time相关的SQL。
SQL ordered by Elapsed Time 的报告信息,按SQL语句执行总时长排序。总时长 ,总是在某一个时间段内,比如一小时或是一天。一般情况下,我们关注的是每执行一次的时间,也就是Elap per Exec(s),它指执行一次SQL的平均时间,单位时间为秒。
但是呢,AWR是针对于全库的,那么怎么查某个SCHEMA的相关 SQL ordered by Elapsed Time 呢?看下面。
--取得实例相关
select instance_number,instance_name,host_name from v$instance;
INSTANCE_NUMBER INSTANCE_NAME HOST_NAME
--------------- ---------------- ----------------------------------------------------------------
1 baoyw baoyw
--取得DB相关
select dbid,name from v$database;
DBID NAME
---------- ---------
2505883968 baoy
--在sqlplus中不以科学计数法显示
set numwidth 30
--取得差异时间 时间段
SELECT e.VALUE - b.value as diff_value
FROM DBA_HIST_SYS_TIME_MODEL B, DBA_HIST_SYS_TIME_MODEL E
WHERE e.dbid = b.dbid
and e.instance_number = b.instance_number
and e.STAT_ID = b.STAT_ID
and B.DBID = '2505883968'
AND B.INSTANCE_NUMBER = '1'
AND B.SNAP_ID = '3128'
AND E.SNAP_ID = '3129'
AND B.STAT_NAME = 'DB time';
dba_hist_sqlstat 和 dba_hist_sqltext 都是历史数据。v$sql_monitor 是监控数据,它有用户信息,所以这里关联查询。按时间倒序。这三张表的详情,自行查查官方文档,相信就明白了。
下面的 a 表中只保留了我需要的字段,b 表也是一样。根据自己的需要来即可。
--查询用户执行一次SQL的平均时间
--&db_time 上面取得的时间差值
set linesize 999
set pagesize 999
set numwidth 30
col "Elapsed Time per Exec (s)" for a30
col "% Total DB Time" for a16
col sql_id for a18
col username for a16
select *
from (select to_char(decode(sqt.exec,0, to_number(null),(sqt.elap / sqt.exec / 1000000)),'9999990.99') as "Elapsed Time per Exec (s)",
to_char((100 * (sqt.elap / &db_time )),9990.0) as "% Total DB Time",
sqt.sql_id
from (select sql_id,
max(module) module,
sum(elapsed_time_delta) elap,
sum(cpu_time_delta) cput,
sum(executions_delta) exec,
sum(iowait_delta) iowt
from dba_hist_sqlstat
where dbid = '2505883968'
and instance_number = 1
and 3128 < snap_id
and snap_id <= 3129
group by sql_id
) sqt,
dba_hist_sqltext st
where st.sql_id(+) = sqt.sql_id
and st.dbid(+) = '2505883968') a,(select distinct user#,username,sql_id from v$sql_monitor where user# in ('54','55')) b where a.sql_id = b.sql_id
order by 1 desc;