上海插花花艺进修学校:db file scattered read等待事件 - oracle - 善待自己,切莫...
db file scattered read等待事件有3个参数:file#,first block#,和block数量.
在处理有关db file scattered read等待事件的时候牢记以下关键想法:
1.oracle会话已经请求并且正等待从磁盘把多个邻近的数据库块(可达db_file_multiblock_read_count数量)读入到SGA。
2.多块I/O请求和全表扫描(full table scans),索引快速扫描(index fast full scans)操作有关
3.看单独会话的两个重要的数字,TIME_WAITED和AVERAGE_WAIT
4.重要的db file scattered read是最可能是一个应用问题
db file scattered read等待事件很像db file sequential read事件。但不是单块读,这是多块读。db file scattered read等待事件发起者是执行对表和索引全扫描操作操作的SQL语句(用户和递归两者)。
你能最小化db file scattered read等待的方法和对db file sequential read一样。
l 优化导致更多等待的SQL语句。目标是最小化物理和逻辑读的数量
l 降低平均等待时间
在9I之前,为SQL语句生成精确的解释计划是一个辛苦的任务,特别如果你的模式没有特权通过SQL语句访问对象。但是,任务现在是轻快的,9I开始有了v$sql_plan视图。以下查询提取了当前执行全表扫描的SQL语句的执行计划:
set linesize 132
break on hash_value skip 1 dup
col child_number format 9999 heading 'CHILD'
col operation format a55
col cost format 99999
col kbytes format 999999
col object format a25
select hash_value,
child_number,
lpad(' ',2*depth)||operation||' '||options||decode(id, 0, substr(optimizer,1,
6)||' Cost='||to_char(cost)) operation,
object_name object,
cost,
cardinality,
round(bytes / 1024) kbytes
from v$sql_plan
where hash_value in (select a.sql_hash_value
from v$session a, v$session_wait b
where a.sid = b.sid
and b.event = 'db file scattered read')
order by hash_value, child_number, id;
如果应用已经运行了一段时间,突然计时许多时间在db file scattered read事件,并且没有任何代码的变动,你可以尝试去检查看是否一个或多个索引已经被drop或变为unusable了。为了判断哪一个索引已经被drop了,你能比较开发,测试和生长库。你也可以检查当DBA_OBJECTS视图中的LAST_DDL_TIME。当索引被创建的时候,oracle在LAST_DDL_TIME字段上贴上日期和时间。ALTER TABLE MOVE命令标志所有相关的索引为unusable。某些分区操作也导致索引被标志为unusable。这包括在hash分区表中增加一个新分区或合并分区;从一个分区表或全局分区索引中drop一个分区;修改分区属性;合并,移动,或truncate表分区。一个direct load操作的失败,也会让索引们变为unusable状态。通过重建索引是很容易处理的。
初始化参数,当增加值的时候,能让优化器曲解全扫描:
DB_FILE_MULTIBLOCK_READ_COUNT(MBRC),HASH_AREA_SIZE和OPTIMIZER_INDEX_COST_ADJ。查明会话正运行使用的值,做合适的调整,让他们不会反向影响应用的运行时间。
然而,另一个因素也会影响执行计划的品质,导致额外的I/O,它就是有不准确的统计信息。
为什么db file sequential read事件在full table scan操作中显现
--也就是问:在多块读中为什么会有单块读存在
l extent的大小 当扩展区中的最后一组块仅是1个块,oracle使用单块读来提取这个块。这正常来说不是一个问题,除非你扩展区尺寸太小。以下是一个event 10046的trace文件,显示在全表扫描操作中包围的db file sequential read事件。表块尺寸是8K,MBRC是8个块,扩展区尺寸是72K(9个块)。如果表是大的,对表的全表扫描将导致许多db file sequential read事件。如果是这种情况,全表扫描操作将完成的较快,如果表以一个较大的扩展区尺寸重建的话。
l cached block 在multiblock读的一组中的1个或多个块已经在buffer cache中了,因此oracle把fetch分割成2个或多个读,它可以有单块或多块I/O组成。例如,如果MBRC是8,块3和块7是在buffer cache中,oracle将提出3个读呼叫――第一个是块1和块2,第二个是块4 和块6,第三个是块8。因此第三个fetch是单数据块,等待事件就是db file sequential read。然而,对于前2个读呼叫,这等待事件是db file scattered read,因为块的数量是超过1的。因此,被缓存的块能导致全表扫描操作来执行比所需更多的读。
l chained or migrated rows 这就是一个问题,当sql语句的执行计划请求一个全表扫描的时候,如果你看到很多对该表的db file sequential read等待。这象征了表有许多链接或移植的行。Oracle使用单块读i/o来访问每一个链接的或移植的行。检查在DBA_TABLES视图中的表的CHAIN_CNT。当然,CHAIN_CNT是LAST_ANALYZED日期开始的。被移植的行能通过重组表来纠正(譬如export和import,或alter table move)。
l index entry creation 它不是一个问题,当你在sql语句执行计划呼叫一个全表扫描的时候,如果你看见许多针对index的db file sequential read等待。在以下例子中,TABLE_A有一个索引,db file sequential read等待是读index块到SGA来充满来自TABLE_B数据的结果。注意db file sequential read等待与db file scattered read统计数据上比较的数量。这暗示你不能再假设你将从执行计划上就能看到是哪个瓶颈。许多DBAs希望看到许多db file scattered read事件。另一个一文不值的观点就是db file sequential read等待事件不会应用于insert语句。一般的误解就是它仅应用到update和delete语句。