【发布时间】:2017-12-22 10:54:10
【问题描述】:
我在研究典型 ASP.NET MVC 应用程序的缓慢视图时遇到了一个奇怪的现象。其中一个查询无缘无故地运行缓慢。有问题的 LINQ 查询如下所示(Db 是 DbContext):
var testResults = Db.CustomTestResults
.Include(tr => tr.TestMachine.Platform)
.Include(tr => tr.TestCase)
.Include(tr => tr.CustomTestResultAnalysis.Select(tra => tra.AnalysisOutcomeData))
.Where(tr => tr.CustomTestBuildId == testBuild.Id)
.ToList()
.AsReadOnly();
其实没什么特别的。根据过滤器,查询结果集的大小可能会有所不同,最多 10 到 10000 条记录。
从 SSMS 执行的 SQL 生成的查询(由 LINQ 调试日志捕获)运行速度很快,最大的集合大约需要 2 秒,而较小的集合则不到 1 秒。然而,随后由 IIS 运行的奇怪事情发生了。查询开始以慢 1/100 倍的速度运行。较小的需要大约 10 秒来执行,较大的由于查询执行超时而失败。我不确定是否有任何其他查询受到影响,但这只是处理大型数据集,所以最明显的是注意到这个问题。
由于这还不够令人困惑,所以不久前,同样的代码可以按预期完美运行。所以这个bug似乎是由一些外部因素引起的。数据库为 SQL Server 2014 SP2,EF 为 v6.2,IIS 7.5。
如果我能在哪些领域以及如何进一步调查这方面的任何想法,我将不胜感激。
【问题讨论】:
-
使用 XEvent Profiler 或(不推荐使用的)SQL Server Profiler 来捕获围绕 EF 查询执行和 实际 执行计划的事件。 EF 可能设置了意外设置,使用批处理加载数据或使用慢游标——它不应该这样做。扩展事件可以捕获比 SQL Server 分析器更多的东西
-
尝试使用像 Dappert 这样的 microORM 来报告查询,以避免 EF 做出这种不幸的决定。如果您还没有禁用报告查询的更改跟踪,那么您应该禁用更改跟踪,尽管这不能解释数量级延迟
-
顺便说一句,我遇到了同样的问题。几个月后,使用 SSMS 运行良好的查询开始使用 EF 花费更长的时间。更改跟踪被禁用。
-
@PanagiotisKanavos 实际上这很有意义,谢谢。这就解释了为什么性能会无缘无故地突然改变。不幸的是,我没有运行分析器的特权。有什么方法可以规范 EF 使用哪些查询选项,并以某种方式强制它们?
-
如果你不知道发生了什么,你就无法修复它。在 SQL Server 2014 中,跟踪是通过扩展事件完成的,而不是探查器。您不能从 SSMS 启动 XE 会话吗?如果您无法在生产环境中执行此操作,请在测试环境中尝试。事件的顺序将是相同的
标签: sql-server entity-framework linq