字典缓存命中率低于95%不意味必须调大shared_pool_size,应优先排查应用行为;需用v$rowcache实时查命中率并关注dc_objects、dc_users等高miss项,结合latch争用分析与审计日志定位真实根因。

字典缓存(Dictionary Cache,即 Row Cache)命中率低于 95% 不代表必须调大 shared_pool_size,真正要动的往往是应用行为或少数关键配置项。
查当前真实命中率,别只信 AWR 报告快照点
AWR 报告里的 “Row Cache Hit %” 是两个快照之间的聚合值,可能掩盖尖峰波动。直接查实时视图更准:
SELECT (1 - SUM(getmisses)/NULLIF(SUM(gets),0)) * 100 AS "Row Cache Hit Ratio" FROM v$rowcache;
注意:NULLIF(SUM(gets),0) 防止除零;这个值若稳定在 98%+,但 AWR 显示 92%,说明问题集中在某几分钟内——得切到 v$active_session_history 查秒级等待。
常见误操作:只跑一次该 SQL 就下结论。建议间隔 10 秒连跑 3 次,看是否持续下跌。
定位高 miss 的 dc_* 类型,重点盯 dc_objects 和 dc_users
命中率低是表象,v$rowcache 才暴露真凶:
SELECT parameter, gets, getmisses, scans, scanmisses FROM v$rowcache WHERE getmisses > 100 ORDER BY getmisses DESC;
重点关注以下几类:
-
dc_objects:高频查dba_objects、all_tables或用同义词/视图的 SQL,每次 miss 都触发递归查询obj$ -
dc_users:大量不同用户名连接(如未启用连接池)、硬编码ALTER SESSION SET CURRENT_SCHEMA=...、或频繁密码错误登录(RETURNCODE = 1017) -
dc_sequences:序列没设CACHE,比如CREATE SEQUENCE s START WITH 1 INCREMENT BY 1 NOCACHE;,每取一个值都争用 row cache lock -
dc_segments:频繁建临时表、物化视图刷新、或 19c 启用ENABLE_DDL_LOGGING=TRUE但日志表未分区
区分 latch: row cache objects 争用是内存不足还是并发热点
看到 latch: row cache objects 等待高,第一反应不是加内存:
SELECT event, time_waited_micro/1000000 AS sec, waits FROM v$system_event WHERE event = 'latch: row cache objects';
如果平均等待时间
- 监控脚本每 5 秒执行一次
SELECT COUNT(*) FROM dba_objects WHERE owner = 'APP' - 应用层反复调用 PL/SQL 块检查表是否存在:
SELECT COUNT(*) INTO cnt FROM all_tables WHERE table_name = ... - Oracle 12c+ 开启
optimizer_adaptive_features后,自适应统计收集密集刷dc_users和dc_objects
验证是否真缺内存:SELECT bytes FROM v$sgastat WHERE name = 'free memory' AND pool = 'shared pool'; 若长期 > 50MB,基本可排除 shared pool 不足。
优化动作优先级:从应用层到配置,最后才碰 shared_pool_size
改 shared pool 是最不推荐的第一选择。实际有效路径是:
- 禁掉低效元数据查询:把
dba_*改成user_*,或用all_*加明确owner过滤 - 序列加
CACHE 1000:ALTER SEQUENCE s CACHE 1000;(注意重启后 cache 重置) - 查密码错误源头:
SELECT username, returncode, timestamp FROM dba_audit_trail WHERE returncode IN (1017, 1005) AND timestamp > SYSDATE - 1/24; - 19c 中关闭非必要 DDL 日志:
ALTER SYSTEM SET ENABLE_DDL_LOGGING = FALSE; - 确认无硬编码
CURRENT_SCHEMA,改用连接池统一设置 schema
真正需要调 shared_pool_size 的情况极少——通常是上述所有点都排查完,且 v$sgastat 显示 row cache 占用持续增长、free memory 掉到 10MB 以下,才考虑微调。











