Oracle db file sequential read
产生原因:
该等待事件通常意味着一次I/O读取请求的结束。一次sequential读取通常是单个块的读取,但偶尔的在读取多块的时候也会看到sequential读取。
诊断方法:
在会话级,查询视图V$SESSION_WAIT时如果有该事件存在,那么该视图中的
P1-表示文件编号FILE#
P2-表示块编号BLOCK#
P3-表示读取的块数BLOCKS,也就是数据库在FILE#上第BLOCK#开始读取的数据库块数。
在实例级,通过STATSPACK报告中的FILE IO和TABLESPACE IO部分可以判断出读取最频繁的表空间或数据文件。
通过下面的查询可以搜索出那些会话正在执行顺序读取:
SELECT sid, total_waits, time_waited
FROM v$session_event
WHERE event='db file sequential read'
and total_waits>0
ORDER BY 3,2;
通常的解决方法:
块读取通常是不可避免的,但可以通过最小化不必要的IO避免不必要的块读取。
检查使用了不合适的索引扫描的SQL,优化SQL语句;
可能的话加大SGA中的数据库缓存池以缓冲更多的数据库表块和索引块;
重新组织数据库表,比如使用export、import或者CTAS以使表有更好的聚集,关于数据库表的聚集因子cluster_factor请参考biti_rainy的blog;
判断表是否适合分区以减少需要查询的数据块总数;
1.根据收集的等待事件,分析是那些对象以及对应的sql。
2.确定是那些对象,执行如下:
SELECT segment_name, partition_name, p1, p2
FROM dba_extents ,v$session_Wait wait1
WHERE wait1.p2 BETWEEN block_id AND (block_id + blocks - 1)
AND file_id = wait1.p1
ORDER BY segment_name;
3.确定执行的sql语句,执行如下:
SELECT hash_value, address, piece, sql_text
FROM v$sqltext
WHERE hash_value IN (SELECT DISTINCT hash_value
FROM wait1)
ORDER BY hash_value, piece;
SELECT hash_value, address, piece, sql_text
FROM v$sqltext
WHERE hash_value = :1
ORDER BY hash_value, piece;
注意这个有可能一些已经不在shared pool。
4.另外通过这个脚本也可以确定对象,缺点这个块一定要读入sga。
SELECT DISTINCT a.object_name, a.subobject_name
FROM dba_objects a, SYS.x_$bh b
WHERE (a.object_id = b.obj OR a.data_object_id = b.obj)
AND b.file# = :p1
AND b.dbablk = :p2