总结:我们遇到的问题是EF4查询编译时间超过12秒。缓存查询只会让我们到目前为止;我们有什么办法可以减少编译时间吗?有什么我们可能做错了我们可以寻找吗?谢谢!
我们有一个通过WCF服务公开的EF4模型。对于我们的每个实体类型,我们公开了一个方法来获取并返回整个实体以进行显示/编辑,包括许多引用的子对象。
对于一个特定的实体,我们必须.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,但客户认为最终用户仍然无法接受。
所以我们真的需要以某种方式减少查询编译时间。有什么想法吗?
我不明白为什么在32个表格中生成一个选择需要12-15秒,所以我很乐观有一些改进的余地!
感谢您的任何建议!我们正在针对SQL Server 2008运行,如果重要,XP / 7 / server 2008 R2使用RTM VS2010。
答案 0 :(得分:7)
让您的查询更简单。认真;查询复杂性和编译时间之间存在几乎线性的关系。两个简单查询通常比一个非常复杂的查询快得多(即使预编译!)。如果速度是最终目标,请选择最快的选项。
答案 1 :(得分:4)
您可以为一些更复杂的查询创建视图,从而完全控制SQL。然后在数据模型中包含该视图。
答案 2 :(得分:1)
这可能不是您正在寻找的答案,但是对于一个简单的解决方法,为什么不在webapp初始化(对webapp执行一些虚拟调用)而不是第一次运行时运行CompiledQuery.Compile(客户)电话。
答案 3 :(得分:1)
您可以尝试使用http://www.iis.net/download/ApplicationWarmup 它现在处于测试阶段,但我们也在考虑使用它。
答案 4 :(得分:1)
查看nqueries,它使用在应用程序启动期间生成的预编译查询。
编辑: 由于切换到EF5,NQueries在切换到DbContext时不再支持编译查询,如果您仍想查看,请使用1.03 release source code,它仍然是基于ObjectContext并支持编译查询。