查result cache命中率需计算find count/(find count+create count),重点关注v$result_cache_statistics等三个视图;若长期低于0.7,表明缓存利用率低,多因invalidation过高导致反复重建。
查 result cache 命中率该看哪几个关键指标
awr 报告里没有直接叫“命中率”的汇总数字,得自己算。核心就三个视图:v$result_cache_statistics 提供累计计数,v$result_cache_memory 看内存分布,而真正反映业务效果的是 dba_hist_result_cache_statistics(历史快照),配合 awr 报告里的 “result cache statistics” 小节交叉验证。
重点关注这三项:
-
Find Count:成功从缓存取结果的次数(即“命中”) -
Invalidation Count:因底层对象变更触发的缓存失效次数 -
Create Count:新结果集被写入缓存的次数(含首次执行和重载)
命中率 ≈ Find Count / (Find Count + Create Count);如果这个值长期低于 0.7,说明缓存利用率偏低,不是没用上,就是频繁失效。
为什么 Invalidations 高但 Find Count 却很低
这是最典型的误用信号:缓存建了,但几乎没被复用。常见原因不是 SQL 写法问题,而是依赖对象太“脆”——比如缓存结果依赖一张经常被 TRUNCATE 或 INSERT /*+ APPEND */ 的表,哪怕只改一行,只要触发了 DML,Oracle 就会把所有依赖它的 result cache entry 标为 invalid,后续第一次访问就得重新执行并重建缓存。
排查时盯死这几处:
- 检查
INVALIDATION_COUNT和CREATE_COUNT是否接近甚至超过FIND_COUNT - 用
SELECT * FROM V$RESULT_CACHE_DEPENDENCY查哪些缓存项绑定了高频更新的表 - 确认应用是否在事务里混用了
RESULT_CACHE查询和 DML(尤其同事务内先查后改)
注意:RESULT_CACHE 不感知细粒度数据变更,只认对象级 DDL/DML,所以对 OLTP 表基本不友好。
如何判断是不是 Result Cache 在拖慢解析或内存
Result Cache 本身不参与 SQL 解析,但它会增加硬解析后的“缓存注册”开销,且所有缓存对象都占 shared_pool。当看到 library cache lock 或 latch: shared pool 等待上升,同时 V$RESULT_CACHE_MEMORY 显示 BUCKET_COUNT 远大于 ROW_COUNT(说明哈希桶碎片严重),就要怀疑它了。
临时缓解方法:
- 调低
result_cache_max_size(默认是shared_pool_size的 0.25),避免抢占关键 latch 资源 - 禁用高频率、低复用 SQL 的 hint:
/*+ NO_RESULT_CACHE */ - 确认
result_cache_mode是MANUAL而非FORCE(后者会让所有可缓存查询强制进 cache)
特别注意:RESULT_CACHE 的内存块无法被 ASMM 自动回收,一旦分配就常驻 shared pool,直到实例重启或手动 EXEC DBMS_RESULT_CACHE.FLUSH。
用 AWR 报告定位具体哪条 SQL 缓存失效最狠
标准 AWR 报告的 “SQL Statistics” 部分默认不展示 result cache 相关列,必须自定义。最快的方式是查 DBA_HIST_SQLSTAT 中带 RESULT_CACHE hint 的 SQL:
SELECT sql_id, plan_hash_value,
SUM(result_cache_count) cnt,
SUM(result_cache_invalidations) inv
FROM dba_hist_sqlstat
WHERE result_cache_count > 0
AND snap_id BETWEEN &start_snap AND &end_snap
GROUP BY sql_id, plan_hash_value
ORDER BY inv DESC;
再结合 DBA_HIST_SQL_PLAN 确认该 SQL 是否真用了 RESULT_CACHE 操作符(operation = 'RESULT CACHE')。如果某条 SQL 的 inv 极高但 cnt 很低,基本可以判定它在反复“建了又毁”,不如关掉。
真实环境里,90% 的 result cache 问题出在缓存生命周期和业务更新节奏完全错配——不是技术没生效,是它根本不该出现在那个场景里。










