您的位置:首页 > 数据库 > Oracle

大量read by other session导致oracle性能低

2016-07-29 15:46 585 查看
场景:测试库压力测试,用户反应oracle库很慢很慢

1检查等待事件:

select event,count(1) from  v$session_wait group by event order by  2 desc;

发现 read by other session 排第一。

2找到read by other session的SQL,同时可以取一个AWR报告看看TOP SQL,都指向同一SQL。

select sid,

       s.username,

       s.program,

       s.action,

       logon_time,

       q.sql_text,

       q.SQL_FULLTEXT,

       q.sql_id

  from v$session s

  left join v$sql q on s.sql_hash_value = q.hash_value

 where s.sid in (select sid

                   from v$session_wait

                  where event in ('read by other session'));

3、找到绑定变量,执行一下SQL,看看SQL是执行计划。此时可以做一个10053事件,看看为啥是这样的执行计划。

    但是SQL很明显是走了一个错误的索引。

    select * from v$sql_bind_capture where sql_id='f2wthw8rn4706';

4、CBO计算执行计划是根据统计信息,错误的执行计划很可能是统计信息不准确。经查询,果然是统计信息不准确。收集统计信息或者加hint解决问题。

begin

  dbms_stats.gather_table_stats(ownname          => 'OWNER',

                                tabname          => 'TABLE_NAME',

                                estimate_percent => 100,

                                block_sample     => CASE 'FALSE' WHEN 'TRUE' THEN TRUE ELSE FALSE END,

                                method_opt       => 'FOR ALL COLUMNS SIZE REPEAT',

                                degree           => 4,

                                granularity      => 'ALL',

                                cascade          => TRUE,

                                no_invalidate    => CASE 'FALSE' WHEN 'TRUE' THEN TRUE ELSE FALSE END);

end;

/

知识补充:

read by other session这个等待事件其实是oracle IO问题一个比较尴尬的场景,会话a在进行把磁盘上的数据块读到内存(data buffer cache)中这个操作,会话b,会话c 同时也请求这个数据块。因为会话a还完全读入内存(data buffer cache),就导致了b,c read by other session。所以会话a一般是db file sequential read  或 db file scattered read。

这个是oracle 10g 从oracle 9i的buffer busy waits中分离出来的,也是一种热块现象。

当出现该问题如何解决?

一般出现该问题是由于sql导致的,或者是由于磁盘设备可能导致。

当出现该问题的时候,首先需要定位sql。

方法一:通过ash获得细粒度的报告,查看top sql statement 获得sql。

方法二:通过sql语句直接获得:

1、当前正在发生的问题:

select sql_fulltext from v$sql a,v$session b where a.sql_id=b.sql_id and b.event='read by other session';

2、历史曾经发生的

select a.sql_id,sql_fulltext from v$sql a,dba_hist_active_sess_history b where a.sql_id=b.sql_id and b.event='read by other session';

往往read by other session伴随着db file sequential read事件的出现。

另外可以查看涉及对象信息,此处就是p1,p2,p3

SELECT p1 "file#", p2 "block#", p3 "class#"

FROM v$session_wait WHERE event = 'read by other session';

通过p1,p2,p3获得热点对象:

SELECT relative_fno, owner, segment_name, segment_type FROM dba_extents

WHERE file_id = &file

AND &block BETWEEN block_id AND block_id + blocks - 1;

另外,也可以 直接查看热点块的信息,如查看热点块导致的sql语句:

select sql_text

from v$sqltext a,

(select distinct a.owner, a.segment_name, a.segment_type

from dba_extents a,

(select dbarfil, dbablk

from (select dbarfil, dbablk from x$bh order by tch desc)

where rownum < 11) b

where a.RELATIVE_FNO = b.dbarfil

and a.BLOCK_ID <= b.dbablk

and a.block_id + a.blocks > b.dbablk) b

where a.sql_text like '%' || b.segment_name || '%'

and b.segment_type = 'TABLE'

order by a.hash_value, a.address, a.piece;

查看热点块对象:

SELECT E.OWNER, E.SEGMENT_NAME, E.SEGMENT_TYPE

FROM DBA_EXTENTS E,

(SELECT *

FROM (SELECT ADDR, TS#, FILE#, DBARFIL, DBABLK, TCH

FROM X$BH

ORDER BY TCH DESC)

WHERE ROWNUM < 11) B

WHERE E.RELATIVE_FNO = B.DBARFIL

AND E.BLOCK_ID <= B.DBABLK

AND E.BLOCK_ID + E.BLOCKS > B.DBABLK;


找到sql之后需要做的就是查看执行计划,判断问题所在,并进行优化。


 1、对于在shared pool存在的cursor可以通过如下命令查看执行计划select * from table(dbms_xplan.display_cursor('sql_id',null,'allstats'));2、对于历史可以通过查看awr信息获得:
select * from table(dbms_xplan.display_awr('sql_id'));另外对于设备引起的需要查看磁盘读写信息,可以通过vmstat 2 200进行判断。


   


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: