今天用户反应系统很慢,做了一个AWR发现有大量read by other session等待事件,伴有大量的db file sequential read的等待事件:
read by other session等待事件说明:
当我们请求一个数据时,Oracle 第一次会从磁盘将数据读入buffer cache。如果有两个或者多个session 请求相同的信息,那么第一个session 会将这个信息读入buffer cache,其他的session 就会出现等待。 在10g之前,该等待事件还是在bufferbusy waits 之下,在Oracle 10g之后,单独将该事件拿出并命名为read by other session。一般来说出现这种等待事件是因为多个进程重复的读取相同的blocks,比如一些session 扫描相同的index或者在相同的block上执行full table scan。解决这个等待事件最好是找到并优化相关的SQL语句。Readby other session 等待的出现也说明数据库存在读的竞争,所以该等待事件通常和db file sequential read或db file scattered read 同时出现。
解决方法:
- 通过awr找出相应的sql,进行优化。
- 查看对应SQL的执行计划是否最优,必要时可以通过DBMS_SQLTUNE包进行优化,通过SQL_PROFILE文件稳固执行计划。
- 查看表和索引的统计信息是否陈旧,必要时收集统计信息。
- 调整pctfree参数,将数据重新导入,打散热块。
以下内容是参考 惜分飞 博客内容:http://www.xifenfei.com/1200.html
1.如果系统中有这种等待事件,我们可以通过以下SQL查询v$session_wait得到详细信息
SELECT p1 "file#", p2 "block#", p3 "class#" FROM v$session_wait WHERE event = ‘read by other session‘;
2.根据FILE#,BLOCK#查询热块对象,其实这部分可以直接从AWR的Segments by Buffer Busy Waits看出来。
SELECT OWNER, SEGMENT_NAME, SEGMENT_TYPE, TABLESPACE_NAME, A.PARTITION_NAME FROM DBA_EXTENTS A WHERE FILE_ID = &FILE_ID AND &BLOCK_ID BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS – 1;
3.可以通过下面的SQL脚本查询到具体的SQL语句.
SELECT /*+rule*/ HASH_VALUE, SQL_TEXT FROM V$SQLTEXT WHERE (HASH_VALUE, ADDRESS) IN (SELECT A.HASH_VALUE, A.ADDRESS 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 HASH_VALUE, ADDRESS, PIECE;
Oracle说产生此等待事件大部分原因是多次全扫描相同的索引或在同一表上多次全表扫描。
eygle对db file scattered read的解释是:
db file scattered read通常显示与全表扫描相关的等待。当数据库进行全表扫描时,基于性能的考虑,数据会分散(scattered)读入Buffer Cache。如果这个等待事件比较显著,可能说明对于某些全表扫描的表,没有创建索引或者没有创建合适的索引。
db file sequential read通常显示与单个数据块相关的读取操作(如索引读取)。如果这个等待事件比较显著,可能表示在多表连接中,表的连接顺序存在问题,可能没有正确的使用驱动表;或者可能说明不加选择地进行索引。
在大多数情况下我们说,通过索引可以更为快速的获取记录,所以对于一个编码规范、调整良好的数据库,这个等待很大是很正常的。但是在很多情况下,使用索引并不是最佳的选择,比如读取较大表中大量的数据,全表扫描可能会明显快于索引扫描,所以在开发中我们就应该注意,对于这样的查询应该进行避免使用索引扫描。