只有在asmm模式(memory_target=0且sga_target>0)下,v$db_cache_advice的建议才可信;amm模式下size_factor

先确认你用的是 ASMM 还是 AMM 模式
v$sga_target_advice 和 v$db_cache_advice 的建议值,只在 ASMM 模式(memory_target = 0 且 sga_target > 0)下可信。如果 memory_target > 0,说明启用了 AMM,此时 Oracle 会动态拆分 SGA/PGA,v$db_cache_advice 输出的 SIZE_FACTOR 小于 1 的行是降级模拟,不能当真扩容依据。
执行这条语句快速判断:
SELECT name, value FROM v$parameter WHERE name IN ('memory_target', 'sga_target');
若结果是 memory_target = 0 且 sga_target = 4G,才继续看 v$db_cache_advice;否则应先停用 AMM(设 memory_target = 0),再重启启用 ASMM。
怎么看 v$db_cache_advice 里的拐点
运行 SELECT * FROM v$db_cache_advice ORDER BY size_for_estimate; 后,重点不是找 ESTD_PHYSICAL_READS 的绝对最低值,而是观察“突降之后是否还有明显收益”:
- 若从 6G → 8G,
ESTD_PHYSICAL_READS从 9200 降到 8950;再从 8G → 10G,只降到 8942 —— 后一档收益几乎为零,那 8G 就是性价比终点 - 必须检查该尺寸是否对齐
V$SGAINFO.GRANULE_SIZE(比如粒度是 4MB,就别设 7.3G,得取整到 7.2G 或 7.6G) - 跳过所有
SIZE_FACTOR 的行 —— 它们是压缩或降级模拟,不是真实扩容建议
调完 db_cache_size 物理读反而升了?先查执行计划偏移
常见于 OLTP 系统:buffer cache 变大后,优化器误判全表扫描成本更低,把原本走索引的 SQL 改成 TABLE ACCESS FULL,逻辑读没增、物理读暴增。
排查步骤:
- 比对 AWR 中 “SQL ordered by Reads” 和 “SQL ordered by Gets”,看高物理读 SQL 是否也出现在高逻辑读 Top 中
- 查
V$SQL_PLAN,确认对应 SQL 的OPERATION是不是从INDEX RANGE SCAN变成了TABLE ACCESS FULL - 临时加 hint 或用
ALTER SYSTEM SET "_optimizer_ignore_hints"=TRUE测试,排除绑定变量窥探干扰
别只盯 db_cache_size,shared_pool 可能被挤爆
v$db_cache_advice 只管 buffer cache,但 SGA 是共享池 + 数据缓存 + 其他组件的总和。盲目拉高 db_cache_size,可能让 shared_pool 剩余内存跌破安全线:
- 查
V$SGASTAT中shared pool下的free memory:小系统至少留 100MB,大系统建议 ≥ 5% 总 SGA - 看 AWR 的 “Shared Pool Statistics” 里 “% SQL with Version Count > 1” 是否超 15% —— 超了说明硬解析已紧张,此时扩 buffer cache 是火上浇油
- 优先用
ALTER SYSTEM SET sga_target = <new_value></new_value>,让 Oracle 自动 rebalance;手动设db_cache_size+shared_pool_size容易失衡
Granule 对齐、执行计划漂移、shared pool 挤占——这三个点不检查,光按 Advisory 数字调大小,大概率越调越慢。











