physical reads / logical reads比值骤升(如0.02→0.15)即需优先排查sql,而非调db_cache_size;应结合awr中sql ordered by physical reads、disk_reads/buffer_gets>0.3及tablespace io stats的avg rd(ms)>20ms综合诊断。

物理读过高不等于SQL一定有问题,但Physical Reads在Load Profile里突然飙升,且Physical Reads / Logical Reads比值显著上升(比如从0.02跳到0.15),就该立刻查SQL,而不是先调DB_CACHE_SIZE。
看Load Profile里的比值,不是只盯Physical Reads绝对值
AWR报告开头的Load Profile节里,有两行关键指标:Physical Reads和Logical Reads。单独看Physical Reads = 331.9 blocks per second没意义——得算比值:Physical Reads / Logical Reads。正常OLTP业务这个值应
常见误判:看到Physical Reads数值大,就加DB_CACHE_SIZE。但若Buffer Hit Ratio仍>95%,说明物理读来自合理场景(如大表扫描、临时结果集),强行扩缓存反而挤占SHARED_POOL,引发latch: shared pool争用。
- 先确认是否真异常:对比高峰段与低峰段报告,看比值是否同步跳变
- 排除干扰:跳过
SQL*Net message from client这类空闲事件主导的报告,它们的物理读常是假象 - 注意单位:
Physical Reads单位是block,不是byte;8K块下10000 blocks ≈ 78MB,别直接换算成磁盘吞吐量
定位高物理读SQL:优先看SQL ordered by Physical Reads
翻到AWR报告的SQL Statistics → SQL ordered by Physical Reads部分。这里排第一的SQL,未必是罪魁祸首——要看它的Executions和Physical Reads Per Exec:
- 若
Physical Reads Per Exec> 10000 且Executions> 100,基本锁定为全表扫描未走索引 - 若
Physical Reads Per Exec很低(如Executions极高(如>50000),可能是频繁访问小表却未启用缓存(如CACHE提示或KEEP池) - 若
Physical Reads高但Buffer Gets也高,说明逻辑读同样爆炸,大概率是索引缺失或统计信息过期
快速验证:拿到sql_id后查v$sql:SELECT sql_text, disk_reads, buffer_gets, executions FROM v$sql WHERE sql_id = 'xxx'。如果disk_reads / buffer_gets > 0.3,且executions > 1,这条SQL就是优化重点。
结合Tablespace IO Stats确认是不是IO子系统拖慢
物理读高分两种情况:一种是SQL确实需要大量磁盘读,另一种是IO响应慢导致单次读耗时长,进而被AWR统计为“更多等待”。必须下钻到Tablespace IO Stats节:
- 找
Avg Rd(ms)列:持续>20ms说明存储响应慢(机械盘正常 - 看
Avgrd(ms)高的表空间是否对应高物理读SQL的基表?如果是,优先排查存储链路(ASM磁盘组、LUN队列深度、HBA卡) - 若
Avg Rd(ms)正常(Physical Reads仍高,问题100%在SQL层:要么没索引,要么索引失效(如函数索引未用、统计信息陈旧)
注意:Tablespace IO Stats里的Avgrd(ms)是加权平均,不能只看最大值。要观察连续3–5份报告是否稳定偏高。
优化动作要分层:先改SQL,再调参数,最后动架构
物理读优化顺序不能乱。盲目调大DB_CACHE_SIZE或启用RESULT_CACHE可能掩盖真实问题,还带来内存争用风险:
- 第一优先级:对高
Physical Reads Per Exec的SQL补索引,或用/*+ INDEX(t idx_col) */强制走索引(验证后再固化) - 第二优先级:检查
DBA_TAB_STATISTICS,对相关表执行DBMS_STATS.GATHER_TABLE_STATS,尤其注意STALE_STATS = 'YES'的表 - 第三优先级:若SQL已最优但仍有合理物理读(如报表类查询),可考虑将热数据放入
KEEP池:ALTER TABLE t STORAGE(BUFFER_POOL KEEP) - 绝对避免:仅因物理读高就调
SGA_TARGET,除非Free Memory在Buffer Pool Statistics里持续为0且free buffer waits进入Top 5
最易被忽略的一点:某些SQL物理读高,是因为NLS_SORT或NLS_COMP参数漂移,导致索引无法使用。查v$sql的sql_text时,顺手看child_number和plan_hash_value是否频繁变化——若同一sql_id有多个不同plan_hash_value,NLS问题概率极大。











