1.使用v$sqlarea视图查看最糟糕的查询(最消耗磁盘读的sql语句)
select b.username,
a.disk_reads reads,
a.executions exec,
a.disk_reads / decode(a.executions, 0, 1, a.executions) rds_exec_ratio,
a.sql_text sql_statement
from v$sqlarea a, dba_users b
where a.parsing_user_id=b.user_id
and a.disk_reads >1000
order by a.disk_reads desc;
注:把其中的disk_reads换成buffer_gets,进而得到消耗内存最大的sql语句。
2.通过查询v$sql可以查看共享sql区域的每条sql语句的单独信息,而不是像v$sqlarea那样,将语句分组。(查看最占用内存的sql语句)
select *
from (select sql_text,
rank() over(order by buffer_gets desc) as rank_bufgets,
to_char(100 * ratio_to_report(buffer_gets) over(), '999,99') pct_bufgets
from v$sql)
where rank_bufgets < 11;
3.查询v$sessmetric视图来查看再定义的时间间隔内使用物理读,cpu或逻辑读最多的会话。
select to_char(m.end_time, 'yyyy-mm-dd hh24:mi:ss') end_time,
m.intsize_csec / 100 ints,----时间间隔 此值除以100是秒值
s.username username,
s.sid sid,
s.serial# serial_num,
round(m.cpu) cpu100,
m.physical_reads reads,
m.logical_reads gets,
m.hard_parses hard_parse,
m.soft_parses soft_parse,
s.sql_id sql_id
from v$sessmetric m, v$session s
where (m.physical_reads > 1 or m.cpu > 1 or m.logical_reads > 1)
and m.session_id = s.sid
and m.session_serial_num = s.SERIAL#
order by m.physical_reads desc, m.cpu desc, m.logical_reads desc;
可以根据自己的环境适当的调整m.physical_reads > 1 or m.cpu > 1 or m.logical_reads > 1这些阈值,我因是本地测试,索引几乎没什么负载。
4.从dba_hist_sqlstat视图中发现糟糕的sql查询
select dhs.snap_id,
dhs.disk_reads_delta reads_delta,
dhs.executions_delta exec_delta,
dhs.disk_reads_delta /
decode(dhs.executions_delta, 0, 1, dhs.executions_delta) rds_exec_ratio,
dhs.sql_id
from dba_hist_sqlstat dhs
where dhs.disk_reads_delta>1000
order by dhs.disk_reads_delta desc;
其中相同的sql_id可以出现在不同的snap_id(不同的awr快照中)中。
可以根据sql_id从dba_hist_sqltext中查看具体的sql语句。
select st.command_type, st.sql_text
from dba_hist_sqltext st
where st.sql_id = '59v4zh1ac3v2a';