EntityFramework花费过多时间返回简单SQL查询的记录

时间:2015-09-14 18:51:33

标签: entity-framework sql-server-2008 entity-framework-4 ef-code-first database-performance

我已经梳理了这篇旧文章: Why is Entity Framework taking 30 seconds to load records when the generated query only takes 1/2 of a second? 但没有成功。

我测试了查询:

  • 没有延迟加载(不使用.Include相关实体)和
  • 没有合并跟踪(使用AsNoTracking)

由于查询的复杂性和使用Code First模型,我认为我不能轻易切换到已编译的查询,但如果您遇到其他问题,请告诉我......

设置

  • 实体框架'4.4'(.Net 4.0,安装了EF 5)
  • Code First模型和DbContext
  • 直接在托管数据库的SQL Server 2008计算机上进行测试

查询 - 它只是从一个表中返回简单的字段:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[Active] AS [Active], 
[Extent1].[ChangeUrl] AS [ChangeUrl], 
[Extent1].[MatchValueSetId] AS [MatchValueSetId], 
[Extent1].[ConfigValueSetId] AS [ConfigValueSetId], 
[Extent1].[HashValue] AS [HashValue], 
[Extent1].[Creator] AS [Creator], 
[Extent1].[CreationDate] AS [CreationDate]
FROM [dbo].[MatchActivations] AS [Extent1]
  • MatchActivations表与其他表有关系,但为此目的,根据需要使用显式加载相关实体。

结果(来自SQL Server Profiler)

  • 对于Microsoft SQL Server Management Studio查询:CPU = 78毫秒,持续时间= 587毫秒。
  • For EntityFrameworkMUE:CPU = 31毫秒,持续时间= 8216毫秒。

有没有人知道,除了建议使用编译查询时,如果在使用Entity Framework进行这样一个简单的查询时还有其他什么需要注意?

3 个答案:

答案 0 :(得分:0)

许多人遇到问题,由于参数嗅探导致的缓存查询执行计划导致SQL Server在通过ADO.NET运行查询时产生效率非常低的执行计划,同时直接从SQL Server Management运行完全相同的查询Studio使用不同的执行计划,因为默认情况下,查询上的某些标志设置不同。

有些人报告说,通过运行以下一个或两个命令,强制刷新查询执行计划是成功的:

 DBCC DROPCLEANBUFFERS
 DBCC FREEPROCCACHE

但针对此问题的更长期,有针对性的解决方案是使用OPTIMIZE FOROPTION(Recompile)等查询提示,如this article中所述,以帮助确保良好的执行计划首先选择更加一致。

答案 1 :(得分:0)

我认为如果您说的是真的,框架正在做一些时髦的事情,即在管理工作室中运行查询需要半秒,而实体框架需要8.2秒。我的预感是,它试图用那些25K +记录集做一些事情(可能与其他东西绑定)。

您可以下载NP NET Profiler并对您的应用进行一次配置吗? http://www.microsoft.com/en-in/download/details.aspx?id=35370

这个漂亮的小程序将记录每个方法调用及其执行时间,并且基本上从底层提供有关它花费7秒以上的信息。如果这没有帮助,我还建议尝试使用JetBrains .NET分析器。 https://www.jetbrains.com/profiler/

之前的回答表明执行计划可能会被取消,而且在许多情况下都是如此,但有时也需要深入了解确定原因。

答案 2 :(得分:0)

我要感谢Kalagen和其他对此做出回应的人 - 我确实得出了这个结论,但忘记了这篇文章。

它将返回的记录数X处理时间(LINQ / EF I假设)将原始SQL数据重新用于客户端的对象。我在SQL服务器上设置wireshark来监视它与查询后的客户端机器之间的网络流量并发现:

  • SQL Server和SQL Server之间存在持续的网络流量 不同机器(8x)之间的数据包处理速率差异很大
  • 当发生这种情况时,SQL服务器的CPU利用率是< 25%并且没有资源饥饿似乎正在发生(工作集,虚拟内存,线程,句柄计数等)。

所以它基本上是将结果不断转换回EF对象。

有问题的查询BTW是“性能”单元测试的一部分,因此我们最终将其剔除到1秒内更合理的典型网页加载100条记录。很容易通过。

如果有人想要了解实体框架如何处理记录后查询的详细信息,我相信知道这将是有用的。

这是一个有趣的发现,处理时间更多地依赖于客户端计算机而不是SQL服务器(这是一个Intranet应用程序)。