最近某个应用的AWR中总显示“db file sequential read“等待事件位于top 5之首,下面检索下MOS关于这个等待事件的说明。
等待事件: "db file sequential read" Reference Note (文档 ID 34559.1)
这种等待事件是一种IO读请求相关的等待。与”db file scattered read“不同,因为”sequential read“是将数据读到连续的内存(注意:这里指的是读到相连的内存,不是说读取的是连续的数据块。同时一次”scattered read“可以读多个块,将他们分散到SGA的不同buffer)。这一事件通常显示与单个数据块相关的读取操作(如索引读取)。如果这个等待事件比较显著,可能表示在多表连接中,表的连接顺序存在问题,可能没有正确的使用驱动表;或者可能说明不加选择地进行索引。
一次”sequential read“通常是单块读,尽管可能看到对于多个块的”sequential read“(见后面的描述)。这种等待也可能在数据文件头读取中看到(P2=1表明是读取文件头)。
独立的等待:
参数:
P1 = file#file# 指的是Oracle正在读取的文件file#。Oracle8/9中file#是绝对文件号。
block# 指的是Oracle正在读取的块号。一次只能读取一个块。
blocks 这个参数明确了Oracle正在从file#的block#开始读取的块数。通常是”1“,但如果P3>1,那么这就是一次多块读。当从SORT(TEMPORARY)段读取数据时,多块的”db file sequential read“可以在更早的Oracle版本中看到。
等待时间:
IO通常是指对操作系统的一次IO请求-直到IO请求完成的等待的块。当Oracle对操作系统的读请求可以从操作系统文件系统的缓存中得到时,等待时间会非常小。
系统级等待:
IO是一种正常的活动,所以真正关心的是那些不必要的或明显缓慢的IO活动。如果花费在IO上的时间非常大,那么我们能够判断哪部分segement段,Oracle是需要从磁盘中获取的。可以查看ESTAT或STATSPACK报告中"Tablespace IO"和"File IO"节,可以得到一些关于哪些表空间/文件正在用于大部分IO请求,得到IO子系统处理速度的指标。如果花费在等待读的时间非常大,那么找出Oracle正在读哪些segment段是非常有帮助的。可以找到哪些文件正在被读。
找出哪些session正在读,并且通过trace跟踪他们来看IO是否正常,也是对此类等待事件的判断是有帮助的。下面的SQL可以找出哪些session值得跟踪:
SELECT sid, total_waits, time_waitedWHERE event='db file sequential read' and total_waits>0 ORDER BY 3,2;
也可以改下上面的语句:
找出高磁盘读取的session(”DISK_READS“)
找出高物理读的session("physical reads")
降低等待次数和时间:
块的读取往往是无法避免的,所以为了降低等待时间,目标就是最小化不必要的IO。为了达到此目的,就需要良好的应用设计和有效的执行计划。执行计划的改变能够对性能产生非常大的影响。系统级的微小调整通常收货甚微。下面几点可能有用:
(1)、查找使用未加以选择的索引范围(index scan)扫描的SQL。
(2)、更大的buffer cache也许有帮助-需要通过真实增加buffer cache来测试,而不是使用DB_BLOCK_LRU_EXTENDED_STATISTICS参数,(如果有可能导致额外的系统换页,那么就不能增加SGA大小)。
(3)、还有一些不太明显的问题可能影响IO,将数据进行物理聚类的程度如何。例如,假设频繁地从一个表中获取行数据,该表中一列是通过索引范围(index scan)扫描的方式得到两个值。如果这里每个索引块中有100行数据,那么有两个极端:
1. 每行数据都在不同的物理数据块(每个索引块包含的100行数据需要读取100个块)。
2. 所有数据都分配到极少的几个相邻物理数据块(每个索引块只需要读取少量的块)。
预先排序或重组数据可以帮助解决这种极端情况。
1. 分区是否能够用来降低需要读取的数据块数量。
2. 找到引起磁盘中频繁的索引范围(index scan)的文件,将它缓存到操作系统文件系统的缓存中。这样将会允许Oracle读请求可以从操作系统缓存中获得,而不是从磁盘IO中获得。