Oracle数据库IO瓶颈需先看Load Profile和Instance Efficiency:Physical Reads Per Second持续超2000且Logical Reads不高,结合缓存命中率低、%util接近100%、await远高于svctm,可确认真实IO瓶颈。
oracle数据库出现磁盘io瓶颈时,awr报告不是“看热闹”的工具,而是定位io压力来源的手术刀。关键不在于发现db file sequential read或db file scattered read高,而在于确认这些等待是否真实由存储慢导致,还是sql或内存配置不合理引发的“假io”。
怎么看IO是不是真瓶颈:先盯Load Profile和Instance Efficiency
跳过Top 5直接看IO,容易误判。先确认系统负载性质:
-
Physical Reads Per Second持续高于2000,且Logical Reads Per Second不高(比如db_cache_size太小,而非磁盘慢 -
Buffer Hit Ratio低于90%,基本可判定是内存不足或SQL未走索引,物理读高是结果,不是根源 - 对比正常时段的
Redo Size Per Second:若IO飙升同时重做日志写入也翻倍,大概率是应用层批量提交或大事务导致日志写压力传导到数据文件IO
定位具体IO热点:File IO Stats比Top Events更准
Top 5里的db file sequential read只告诉你“有单块读”,但不知道读的是哪个文件。真正要动手优化,得下钻到File IO Stats部分:
- 按
Av I/O Wait (ms)排序,找出平均等待超10ms的数据文件——SSD环境超过5ms就该警惕 - 结合
Physical Reads和Av I/O Wait交叉判断:某文件读次数不多但延迟极高,可能是存储链路问题(如SAN路径拥塞);读次数多且延迟高,才是SQL或索引问题 - 用
dba_data_files查出高延迟文件对应的表空间,再查dba_segments确认哪些表/索引在该表空间内被高频访问
查清谁在制造IO:从SQL Statistics反推执行计划
高IO一定对应高物理读SQL。但别只看SQL ordered by Physical Reads的总值,重点看这三个指标:
-
Physical Reads Per Execution:值大于5000,基本可断定没走索引或索引失效(比如where trunc(date_col) = sysdate) -
Buffer Gets Per Execution远高于Physical Reads Per Execution(比如10:1),说明数据已在缓存,IO压力已缓解;反之接近1:1,说明每次都要从磁盘拉 - 对目标SQL运行
dbms_xplan.display_awr,确认执行计划中是否出现TABLE ACCESS FULL或INDEX FAST FULL SCAN——后者本质也是多块读,等同于全表扫描
容易被忽略的细节:sequential read未必是索引问题
db file sequential read常被默认等同于“索引扫描慢”,但实际还有两种典型场景:
- 小表全表扫描:当表只有几MB,Oracle认为不如单块读取高效,会走
TABLE ACCESS BY INDEX ROWID后回表,表现为sequential read,但根源是统计信息不准或优化器成本计算偏差 - 直接路径读(Direct Path Read)被误标:11g+中大表全表扫描默认走直接路径,本应归为
direct path read,但某些版本或参数下会混入sequential read统计,需结合v$session_wait中p1text字段确认 - 临时表空间IO:如果
File IO Stats里temp文件延迟高,问题不在数据文件,而在排序/哈希连接溢出到磁盘,应调大pga_aggregate_target或改写SQL减少中间结果集











