You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core编译查询缓存命中率偏低排查及失效查询定位咨询

排查EF Core compiled-query-cache-hit-rate低于100%的问题

一、定位无法缓存的查询的方法

  • 开启EF Core的日志记录,把级别调到Debug或Trace,这时候EF Core会输出Compiling query这类日志——每出现一次,就说明对应的查询触发了重新编译。可以专门过滤Microsoft.EntityFrameworkCore.Query这个日志类别,聚焦查询编译相关内容。
  • 用性能分析工具,比如Visual Studio性能探查器、dotTrace,跟踪EF Core的QueryCompiler.CompileQuery方法调用,统计哪些查询被频繁编译。
  • 自查查询里的动态元素:EF Core的查询缓存键是基于查询结构和参数类型/值生成的,以下情况会导致缓存失效:
    • 查询里直接引用了外部非静态变量,未通过参数传递
    • 使用了动态生成的匿名类型,属性顺序或类型发生变化
    • Contains方法传入的集合是每次都新建的对象(哪怕内容完全一致)
    • 查询里包含非确定性函数(比如DateTime.Now)或者EF Core无法翻译的自定义方法

二、针对你提供的代码分析

你怀疑的这段UpdateAsync代码,有几个可能导致缓存失效的点:

  1. !NoReevaluationIsNeededStates.Contains(point.State):你使用的是静态只读List<ProcessState>,EF Core处理集合Contains时,List实例可能会让表达式树节点每次都不一样,导致缓存键不匹配。改成静态数组试试:
    internal static readonly ProcessState[] NoReevaluationIsNeededStates = new[] { ProcessState.Received };
    
    数组是值类型集合,EF Core能更好地识别为常量,从而稳定缓存键。
  2. point.Keys.Contains(referencedKey):这里Keys是映射到PostgreSQL数组的List<string>,只要referencedKey是通过参数传递的,这部分一般不会有问题,但要确认数组映射配置是否正确。
  3. ExecuteUpdateAsync里的SetProperty使用的是枚举常量,不会影响缓存。

另外,其他未展示的查询也要检查:有没有动态拼接Where条件导致每次查询结构不一致?有没有直接使用context的属性或者非静态变量?有没有使用EF Core无法缓存的自定义扩展方法?

三、验证修改效果

修改完成后,通过以下方式确认缓存命中率是否提升:

  • 查看EF Core日志,相同查询不再反复输出Compiling query
  • 监控compiled-query-cache-hit-rate计数器,观察数值是否接近100%

内容的提问来源于stack exchange,提问作者mu88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 04:30:36