ITPub博客

首页 > 数据库 > Oracle > [OWI] Db file sequential read

[OWI] Db file sequential read

原创 Oracle 作者:exem0626 时间:2016-05-03 16:29:26 0 删除 编辑

1. Basic Info

Oracle 是用户请求的数据不在的高速缓冲区的时候,服务器进程将相应的数据文件中的数据块加载到高速缓冲区。即称为常规路径(Conventional Path)I/O。常规路径 I/O 分为多块 (Multi Block) I/O 和单块 (Single Block)I/O。多块 I/O 可一次读取多个连续的块的 I/O 方式,单块 I/O 每次只能读取一个块的 I/O 方式。

在 Oracle 中发生常规路径 I/O 时,可以通过两种等待事件查看是发生了多块 I/O 还是单块 I/O。这两种等待事件就是 db file sequential read 和 db file scattered read 事件。这些事件是 Oracle 中最常发生的等待事件。因为想从数据文件中读取的块时,只能进行多块 I/O 或单块 I/O。

db file sequential read 事件是与单块 I/O 一起发生的等待事件。每执行一次单块 I/O的时候,也发生一次 db file sequential read 等待事件。在单块 I/O 文件中读取一个块的所有操作中皆有可能发生。一般在索引扫描、基于 ROWID 的表扫描、读取控制文件(Control file)、读取文件头 (file header) 的时发生。

2 Parameter & Wait Time 
2.1 Wait Parameters


db file sequential read 等待事件的参数如下。

P1: File#

P2: Block#

P3:块数 (大部分是 1. Oracle 7 版本中读取 Temp 段的时候有高于 1 的情况。但是在推出直接路径(direct path) I/O 功能之后这个值一直是 1 。


2.2 Wait Time
作为 I/O 相关等待事件不发生超时,会话是直到发生指定数量的块的 I/O 结束为止等待。


3. Check Point & Solution 
3.1 Oracle 各 I/O 层对 db file sequential read 的解决方案

将相应数据加载到 SGA 是 I/O 一般工作。因此 db file sequential read 事件是正常的等待事件。因 db file sequential read 等待造成性能问题的情况,大部分是因为低

效率的索引扫描或链接行(Chained Row) 和迁移行 (Migrated Row) 发生额外 I/O 导致的。因为 db file sequential read 等待是和索引有关的,所以会认为跟 db file scattered read 等待相对不那么严重,但要记住使用索引不一定始终比使用 FTS (Full Table Scan) 要好。

以 Oracle 的 I/O 层为基准讨论一下  db file sequential read 等待发生的情况和解决方案吧。


3.1.1 应用层

经常执行低效的 SQL 语句或低效的索引扫描,可能会因为一些不必要的物理 I/O 导致 db file sequential read 等待的增加。

使用选择性 (Selectivity) 差的索引是  db file sequential read 的‘主犯’。使用不当的索引,不只是I/O 还会引起高速缓冲区的争用。 要记住有效使用索引可以对大多数的问题防患于未然。

Oracle 中可使用的索引可分为 B 树(B-Tree) 索引、函数索引 (Function Index)、位图索引 (Bitmap Index)域索引(Domain Index) 等。每个索引都有各自特性,只在特定情况下才会对性能改善有帮助。需要先理解这些索引的工作原理后,生成相应索引的工作态度。

保持最新的统计信息也是很重要的。如果利用 DBMS_STATS 包,可以对数据库里的所有对象以最佳方式生成统计信息。

有时,在 SQL*Plus 的环境下执行正常的索引 SQL语句,在实际应用中执行会因为使用了错误的索引产生  db file sequential read 等待导致性能下降。如果在使用绑定变数的时候也出现这类问题,需要检查是不是使用了绑定变量窥视 (Bind peeking) 功能。从 Oracle 9i 开始基本是激活绑定变量窥视功能使用的。使用了此项功能, 即便是使用绑定变量的 SQL 语句,也是利用最初执行时接受的变量值来建立执行计划。所以在测试环境中,即便是正常执行过的 SQL 语句,也会因为最初执行时接受的数值而产生完全不一样的执行计划。如果能断定是因为这种现象造成  db file sequential read 等待的增加的话建,议把隐含参数的 _OPTIM_PEEK_USER_BINDS 值变更为 False。如果把这个值指定位 false 的时候将不会使用绑定偷窥。


3.1.2 Oracle 内存层
高速缓冲区过小而反复产生物理 I/O 的时候,会增加  db file sequential read 等待。这时 free buffer waits 等待一起发生的概率高。如果 free buffer waits 的等待大范围发生,需要考虑增大高速缓冲区。始终要考虑使用多重缓冲池来有效的使用高速缓冲区。利用多种缓冲池来减少  db file sequential read 等待的原理和减少 db file scattered read 等待的原理是一样的。

虽然创建了有效的索引, db file sequential read 等待比预期还要高的时候,要怀疑下的事项。


  • 聚簇银子 (Cluster Factor) 是否过高?
  • 是否发生过多行链接 (Row Chaining) 或行迁移 (Row migration) ?
  • 高的聚簇因子

聚簇因子是代表索引对表的群集度。Cluster Factor 是假设在内存中只能加载一个块,利用索引扫描需要扫描多少的计算值。说得更准确一点,就是沿着索引的额叶块在 ROWID 值中将符合块编号的第 1~15位的值和以前的 ROWID 相比较后替换的次数。为了了解这个概念来看一下一个例子。有个由5个块组成的索引和5个块组成的表,而一个块中有4个行。那么总行数是5*4=20个。依次扫描索引的过程中读取匹配的表时,可能发生两种极端的情况。

第一、Cluster Factor 过低的情况:包含在一个索引块的 4个 ROWID都包含在一个表块中,通过索引扫描表的时候只需要索引扫描5次+表5次,总共扫描10次就能得到所需的数据。这时 Cluster Factor 为5(表块的扫描次数)。Cluster Factor 的最小值跟表的块一样。

第二、Cluster Factor 过高的情况: 包含在一个索引块中4个 ROWID 都在不同的表块中时,通过索引扫描表的时候 5次(索引块数)+ 5次(索引块数)*4(每个索引块所扫描的表的块数)=25次,这样才能得到需要的数据。这时,Cluster Factor是 20 (表块的扫描次数)。CF的最大值和表行数一样。

假设如果没有内存 I/O 即 Cluster Factor 越高就会越发增加读取表块的次数,随之增加物理 I/O。 即 Cluster越高同过 ROWID 读取的表块的次数也增加, 相应地  db file sequential read 等待也会增加。因为通过高速缓冲区读取过的块,之后不会再发生额外物理 I/O, 所以 Cluster Factor 值高不一定会导致 SQL 语句性能下降。但是用 Cluster Factor 过高的索引来扫描大范围的时候,随之会增加需要读取的表块数,可能给性能造成致命性的影响。



来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31135309/viewspace-2092817/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2016-04-22

  • 博文量
    21
  • 访问量
    18951