ESTD_PHYSICAL_READS突降表明DB_CACHE_SIZE越过临界点后物理读边际收益快速衰减,应找拐点后斜率变平区间作为性价比终点,并验证是否对齐Granule Size、SIZE_FACTOR≥1.0。
Buffer Cache Advisory 里 ESTD_PHYSICAL_READS 突降说明什么
它不直接代表“缓存变好了”,而是反映当前 db_cache_size 下的预估物理读变化趋势。突降通常发生在建议尺寸刚越过某个临界点(比如从 4g 到 6g),意味着再增加 buffer cache 对减少物理读的边际收益已快速衰减。
实操建议:
- 别只盯着最低点——找“拐点后斜率明显变平”的区间,比如
ESTD_PHYSICAL_READS从 12000 降到 11800 再到 11795,后两档增幅几乎为零,那前一档就是性价比终点 - 确认该建议值是否落在
V$SGAINFO的Granule Size对齐边界上;Oracle 只能按粒度分配,若建议是 5.3G 但粒度是 4M,实际生效的是向下/向上取整后的值 - 检查
V$DB_CACHE_ADVICE中对应SIZE_FOR_ESTIMATE行的SIZE_FACTOR是否 ≥ 1.0——小于 1 是压缩或降级模拟,不能当真实扩容依据
为什么 DB_CACHE_SIZE 扩容后 V$SYSSTAT 里 physical reads 没降反升
常见于 OLTP 系统误将大表全扫描 SQL 带入分析周期:buffer cache 变大后,优化器更倾向走全表扫描(因逻辑读成本看似更低),反而触发更多磁盘读;或者 DBWR 写压力增大,引发 checkpoint 频繁,间接推高读等待。
实操建议:
- 比对 AWR 报告中 “SQL ordered by Reads” 和 “SQL ordered by Gets”,看 top 物理读 SQL 是否也是 top 逻辑读 SQL——若是,大概率是执行计划偏移
- 查
V$SQL_PLAN中对应 SQL 的OPERATION字段,确认是否从INDEX RANGE SCAN变成了TABLE ACCESS FULL - 扩容前先用
ALTER SYSTEM SET "_optimizer_ignore_hints"=TRUE临时禁用 hint 测试,排除绑定变量窥探或 hint 强制导致的异常
SGA 内存扩容时 SHARED_POOL_SIZE 和 DB_CACHE_SIZE 的配比陷阱
AWR 的 Buffer Cache Advisory 只管 buffer cache,但 SGA 是整体内存池。盲目按建议值拉高 DB_CACHE_SIZE,可能挤占 shared pool,导致 library cache latch 争用、硬解析飙升、甚至 ORA-04031。
实操建议:
- 查
V$SGASTAT中free memory在 shared pool 下的剩余量,确保扩容后仍 ≥ 100MB(小系统)或 ≥ 5% 总 SGA(大系统) - 观察 AWR 中 “Shared Pool Statistics” 部分的
% SQL with Version Count > 1,若 > 15%,说明已有大量重复 SQL,shared pool 紧张,此时优先调优而非扩 buffer - 用
ALTER SYSTEM SET SGA_TARGET = <new_value></new_value>而非手动设各组件,让 Oracle 自动 rebalance(前提是未启用LOCK_SGA)
如何验证 Buffer Cache Advisory 建议在真实负载下有效
AWR 数据基于历史采样,而真实业务有突发性、会话分布变化、绑定变量倾斜等问题,静态建议容易失效。
实操建议:
- 用
DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT在扩容前后各打一个快照,等 15–30 分钟稳定后再比对physical reads和db block gets的 delta - 重点看
V$BUFFER_POOL_STATISTICS中PHYSICAL_READS与DB_BLOCK_GETS + CONSISTENT_GETS的比值,理想应 - 检查
V$OBJECT_USAGE和dba_indexes的monitoring状态,确认高频访问对象是否真被缓存——有些大索引即使 cache 够,也可能因 LRU 算法被踢出
Buffer Cache Advisory 给的是理论最优解,但 Oracle 的内存管理是动态博弈。最常被忽略的不是数值本身,而是它背后那个隐含前提:工作负载稳定、无严重绑定变量窥探、且 shared pool 没成为瓶颈。










