物理读不可能真正多于逻辑读,AWR中出现该现象必因统计口径错误、指标误读或采样异常;根本原因是Oracle内部强制logical reads≥physical reads。
物理读(physical reads)不可能真正“比逻辑读(logical reads)还多”——这是数据库底层机制决定的。如果你在awr报告里看到 physical reads 数值 > logical reads,那基本可以断定:数据源或统计口径被污染了,或者你误读了指标位置。
看错地方:Physical Reads 和 Logical Reads 不在同一统计维度
AWR报告中存在两组完全独立的读取计数,常被混淆:
-
Load Profile区域的Logical Reads和Physical Reads是“每秒/每事务”的速率值(单位:blocks/sec 或 blocks/txn),它们可直接比较比例,但不能简单比大小; -
Instance Efficiency Percentages下的Buffer Hit %是派生值:(1 − physical reads / logical reads) × 100,这里才要求logical reads ≥ physical reads; - 若你在
SQL Statistics → SQL ordered by Physical Reads里看到某条SQL的disk_reads高于另一条SQL的buffer_gets,这完全正常——因为它们属于不同SQL、不同执行次数,不具备跨语句加总可比性。
典型误判场景:把“Top SQL的 disk_reads 总和”和“全库 logical reads 每秒值”放一起比,就像拿一小时的快递单量去比单个快递员一分钟的步数。
真出现 physical reads > logical reads 的唯一可能:采样窗口异常或统计重置
Oracle内部逻辑强制 logical reads = consistent gets + db block gets,而 physical reads ≤ logical reads 是硬约束。突破该约束只发生在以下情况:
- AWR快照期间执行过
ALTER SYSTEM FLUSH BUFFER_CACHE,导致后续所有读都变物理读,但logical reads计数因缓存清空而被重置或延迟上报; - 数据库启用了
DB_FLASHBACK且大量回滚段访问触发一致性读构造,此时consistent gets可能被低估(尤其在高并发长事务下); - 使用了外部表(
ORACLE_LOADER)或 Data Pump 直接路径读,这类I/O不计入logical reads统计,但会反映在physical reads中; - RAC环境中节点间统计未完全同步,跨实例聚合时产生重复计数(尤其在
v$sysstat视图直查时)。
验证方式:运行 SELECT name, value FROM v$sysstat WHERE name IN ('session logical reads', 'physical reads');,对比两个值——只要这个查询结果满足 physical reads ≤ session logical reads,就说明AWR里的“异常”是展示聚合问题,不是真实违反机制。
全表扫描如何推高 physical reads 却未必拉低 buffer hit
全表扫描(FULL TABLE SCAN)本身不必然导致高 physical reads,关键看表是否“热”:
- 冷表首次扫描:全部块从磁盘加载 →
physical reads高,buffer hit瞬间跌; - 热表反复扫描:块已在
buffer cache中 →physical reads为0,但logical reads极高(比如1亿行表扫一次就是上百万consistent gets); - 大表+小
db_cache_size:只缓存部分块,每次扫描都命中一部分、miss一部分 →physical reads持续稳定在中高位,buffer hit卡在70%~85%,最迷惑人; - 注意
direct path read:当全表扫描数据量超过_small_table_threshold(默认2% buffer cache),Oracle自动切到直接路径读,绕过buffer cache → 这类读计入physical reads,但不增加logical reads,也不影响buffer hit计算——这才是真正让“physical reads 看似反超”的元凶。
查证是否发生直接路径读:SELECT event, waits FROM v$session_event WHERE event = 'direct path read'; 或在AWR的 Top 5 Timed Events 中找该事件。
IO负载判断不能只盯 physical reads 数值本身
高 physical reads 是否构成瓶颈,取决于它背后的I/O质量:
- 看
Average Synchronous Single-Block Read Latency:持续 > 20ms 表示存储响应慢,哪怕physical reads只有100/s也危险; - 看
Physical Read Total IO Requests Per SecvsPhysical Read Total Bytes Per Sec:前者高后者低 → 小IO随机读多(索引扫描或碎片化表),后者高前者低 → 大IO顺序读多(全表扫描或分区剪枝); - 对比
db file sequential read和db file scattered read的等待时间与次数:前者占比高通常意味着索引效率差或链式行多;后者占比高则要检查是否缺失分区裁剪或并行度设置不当; - 警惕“伪高IO”:归档日志写入(
ARCH进程)、RMAN备份、甚至DBMS_STATS收集统计信息时的采样扫描,都会推高physical reads,但和业务SQL无关。
真正需要干预的信号,是 physical reads 上升的同时,DB Time 显著增长 + Top 5 Timed Events 中 User I/O 类事件占据主导 + 对应SQL的 elapsed_time 和 disk_reads 强相关——脱离这三者的任意一个谈“物理读多”,都是在调优真空里打转。











