awr中latch: row cache objects等待高,表明高频访问数据字典缓存(如dc_objects、dc_users),非shared_pool_size不足所致;应查v$system_event确认其占db time比例,结合v$latch_misses的where列(如kqrpre: find obj)及v$sql中含dba_、all_、v$的sql定位源头,优先优化访问频次而非调大内存。

AWR里出现大量 latch: row cache objects 等待,基本说明数据库正在高频访问或修改数据字典缓存(dc_* 条目),不是 shared_pool_size 小,而是某类操作在“猛敲”字典缓存的门。
怎么确认是 latch: row cache objects 在主导争用
别只看 AWR 报告顶部的 Top 5 Events。先查真实影响:
-
SELECT event, time_waited_micro/1000000 AS sec, waits FROM v$system_event WHERE event = 'latch: row cache objects'—— 如果sec占 DB Time 超过 20%,就是主力瓶颈 - 再跑
SELECT * FROM v$latch_misses WHERE latch = 'row cache objects',重点看where列:如果高频出现在kqrpre: find obj或kqreqd: reget,说明大量会话在反复查找对象定义(比如表、索引、同义词) - 结合
v$session查等待会话的sql_text:SELECT sql_id, sql_text FROM v$sql WHERE sql_id IN (SELECT sql_id FROM v$session WHERE event = 'latch: row cache objects'),90% 以上会指向含dba_、all_、v$的查询,或是带同义词、视图嵌套、动态ALTER SESSION SET CURRENT_SCHEMA的语句
哪些操作会高频触发 row cache objects latch 争用
这不是内存不够的问题,而是“单位时间敲门次数太多”。常见真实场景:
- 应用未启用连接池,用大量不同用户名直连(比如每个请求生成一个新用户),每次都会触发
dc_users校验 - SQL 中大量使用同义词(
SELECT * FROM my_syn),每次执行都要解析同义词指向的真实对象,反复查dc_objects - PL/SQL 块里写
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || table_name,且table_name变化频繁 → 每次都查dc_objects+dc_segments - 19c 中
optimizer_adaptive_features=TRUE(默认开启)时,自适应统计收集会密集访问dc_users和dc_objects,尤其在高并发 DML 后 - 频繁 DDL:如每分钟建/删临时表、物化视图刷新、启用
ENABLE_DDL_LOGGING=TRUE但日志表未分区,导致dc_logstdby类缓存持续失效
为什么调大 SHARED_POOL_SIZE 通常没用
因为 row cache 占用本身极小(几 MB 级),v$sgastat 里查 row cache 行一般就占 2–5MB。盲目加大 shared pool:
- 无法缩短
kqrpre这类 latch 获取路径,争用点仍在内存结构入口 - 反而可能加剧
library cache或shared pool其他 latch(如library cache lock)的链表遍历开销 - 若已有碎片(
v$sgastat显示大量 4KB/8KB free memory),加内存只会让碎块更多 - Oracle 官方文档也明确说:对
row cache,“tuning options are so limited”,它本质是非可调组件,优化方向只能是减少访问频次
真正该做的三件事
不是改参数,是砍源头:
- 查出高频触发者:
SELECT sql_id, sql_text FROM v$sql WHERE sql_text LIKE '%dba_%' OR sql_text LIKE '%all_%' OR sql_text LIKE '%v$%'—— 干掉那些监控脚本、GUI 工具、开发写的“检查表是否存在”的 PL/SQL - 禁用不必要的自适应特性:
ALTER SYSTEM SET optimizer_adaptive_features = FALSE SCOPE=BOTH(验证后可保留) - 强制绑定 schema 访问:把
ALTER SESSION SET CURRENT_SCHEMA=xxx改成直接用xxx.table_name,避免每次执行都校验用户权限和同义词
最常被忽略的一点:latch: row cache objects 争用从来不是孤立指标,它总是和 dc_objects.getmisses、library cache reloads、parse_calls/executions 异常同步升高——盯住这三个数,比盯着 latch 等待时间更早发现问题。











