如何减少Entity Framework 4查询编译时间?

Rup*_*Rup 7 .net entity-framework entity-framework-4

简介:我们遇到的问题是EF4查询编译时间超过12秒.缓存查询只会让我们到目前为止; 我们有什么办法可以减少编译时间吗?有什么我们可能做错了我们可以寻找吗?谢谢!

我们有一个EF4模型,它通过WCF服务公开.对于我们的每个实体类型,我们公开了一个方法来获取并返回整个实体以进行显示/编辑,包括许多引用的子对象.

对于一个特定的实体,我们必须.Include()31个表/子表来返回所有相关数据.不幸的是,这使得EF查询编译过于缓慢:编译和构建7,800行,300K查询需要12-15秒.这是Web UI的后端,需要比这更快.

我们可以做些什么来改善这个?我们可以CompiledQuery.Compile这个 - 在第一次使用之前没有做任何工作,所以有助于第二次和后续的执行,但我们的客户很紧张,第一次使用也不应该很慢.同样,如果托管Web服务的IIS应用程序池被回收,我们将失去缓存计划,尽管我们可以延长生命周期以最大限度地减少这种情况.此外,我无法提前预先编译此方法和/或序列化EF编译的查询缓存(缺少反射技巧).CompiledQuery对象只包含对缓存的GUID引用,因此它是我们真正关心的缓存.(写出来它发生在我身上,我可以在app_startup的后台开始执行所有查询来编译它们 - 这样安全吗?)

然而,即使我们确实解决了这个问题,我们也会根据我们正在搜索的参数动态地使用LINQ-to-Entities子句构建我们的搜索查询:我不认为SQL生成器做得足够好,我们可以移动所有这些逻辑进入SQL层,所以我认为我们不能预先编译我们的搜索查询.这不太严重,因为搜索数据结果使用较少的表,因此编译时间仅为3-4秒而不是12-15,但客户认为最终用户仍然无法接受.

所以我们真的需要以某种方式减少查询编译时间.有任何想法吗?

  • 分析指向ELinqQueryState.GetExecutionPlan作为开始的地方,我试图进入,但没有真正的.NET 4源可用我不能走得太远,并且Reflector生成的源代码不会让我介入函数或在其中设置断点.
  • 该项目是从.NET 3.5升级的,所以我尝试在EF4中从头开始重新生成EDMX,以防它出现问题但没有帮助.
  • 我已经尝试过在这里做广告的EFProf实用程序,但它看起来不会对此有所帮助.无论如何,我的大型查询会崩溃其数据收集器.
  • 我已经通过SQL性能调优运行生成的查询,它已经有100%的索引使用率.我看不出会导致查询生成器问题的数据库有什么问题.
  • 执行计划编译器中是否存在O(n ^ 2) - 将其分解为单独数据加载的块而不是一次可能帮助的所有32个表?将EF设置为延迟加载没有帮助.
  • 我已经购买了预发布的O'Reilly Julie Lerman EF4书,但除了"编译你的查询"之外我找不到任何东西可以提供帮助.

我不明白为什么在32个表中生成一个选择需要12-15秒,所以我很乐观有一些改进的余地!

谢谢你的任何建议!我们正在针对SQL Server 2008运行,如果重要的话,XP/7/server 2008 R2使用RTM VS2010.

Cra*_*ntz 7

使您的查询更简单.认真; 查询复杂性和编译时间之间存在几乎线性的关系.两个简单查询通常比一个非常复杂的查询快得多(即使预编译!).如果速度是最终目标,请选择最快的选项.

  • @ Mahol25你的失败不会使建议不正确.你可以责备你的工具或责备我,但你不能断定我有一个"简单的数据模型"只是因为你得到8次以上的查询.那太傻了. (3认同)