应先看db time与elapsed比值,若db time远小于elapsed(如12分钟 vs 60分钟),说明数据库空闲,调高sga_target无效;仅当db time/elapsed > 1.5(8核下超480分钟/小时)才需深入分析;再查v$sga_target_advice中estd_db_time由明显下降转为持平的sga_size拐点;同时须校验shared pool剩余内存≥100mb,避免buffer cache扩容挤占shared pool引发ora-04031。

看AWR报告头部的DB Time与Elapsed比值,先排除“假瓶颈”
如果DB Time远小于Elapsed(比如 DB Time 12 分钟、Elapsed 60 分钟),说明数据库大部分时间在空闲,SGA再大也没用。这种情况下,sga_target调高只会浪费内存,还可能因粒度对齐导致其他组件被挤占。
真正值得往下看的信号是:DB Time / Elapsed > 1.5(8核机器下超过 480 分钟/小时更需警惕),表明数据库持续承压,此时才需要结合内存建议进一步判断。
查v$sga_target_advice里的ESTD_DB_TIME拐点,不是最低点
运行SELECT * FROM v$sga_target_advice ORDER BY sga_size;后,重点不是找ESTD_DB_TIME最小的那一行,而是看它从明显下降转为基本持平的位置。例如:
-
SGA_SIZE = 580 MB→ESTD_DB_TIME = 11200 -
SGA_SIZE = 725 MB→ESTD_DB_TIME = 10850 -
SGA_SIZE = 870 MB→ESTD_DB_TIME = 10848
从 725 MB 到 870 MB,预估耗时几乎没变,说明 725 MB 就是性价比拐点。再往上加,收益趋近于零,但风险上升——尤其要检查sga_max_size是否够大,否则ALTER SYSTEM SET sga_target=725M会直接报ORA-02097。
对照v$db_cache_advice和v$sgastat,防buffer cache扩容反伤shared pool
v$db_cache_advice里ESTD_PHYSICAL_READS突降,只说明db_cache_size有提升空间,不代表整个sga_target该无脑拉高。ASMM模式下,Oracle会在各组件间自动调配,但shared_pool一旦被挤到临界值,就会引发library cache latch争用或ORA-04031。
实操时必须同步查:
-
SELECT pool, name, bytes FROM v$sgastat WHERE name = 'free memory' AND pool = 'shared pool';—— 确保扩容后仍有 ≥ 100MB 剩余 -
SELECT ROUND(SUM(bytes)/1024/1024,1) mb FROM v$sgastat WHERE pool = 'shared pool';—— 和建议的sga_target增量做减法
如果shared_pool当前只剩 120MB,而建议把sga_target从 6G 拉到 7.5G,那大概率会出问题。
验证sga_target是否已超配:关注SGA_SIZE_FACTOR
在v$sga_target_advice结果中,如果当前sga_target对应行的SGA_SIZE_FACTOR是 1.0,但ESTD_DB_TIME反而比SGA_SIZE_FACTOR = 0.75那行还高,说明当前值已经过大,继续加只会拖慢性能。
这种情况常见于历史调优未清理、或误将OLAP负载周期当作常态来扩容。此时正确的做法不是加,而是降,并观察v$sysstat中physical reads是否同步上升——若上升不明显,就印证了超配判断。
Granule Size 对齐、sga_max_size硬限制、shared_pool剩余空间这三点,漏掉任何一个,调整都可能变成事故。











