【问题标题】:EF6 SQLQuery very slow but database is very fastEF6 SQLQuery 非常慢,但数据库非常快
【发布时间】:2015-10-30 03:10:07
【问题描述】:

我有一个性能问题,我们进行了一堆分析并被卡住了。希望你们中的一个人以前见过这个。

我正在调用DbContext.Database.SqlQuery,数据库部分需要 3 毫秒,但完整执行需要 9 秒。

我们使用 EF Profiler 发现了这一点,我们还直接在 SQL Server Management Studio 中运行 SQL,它是即时的。

我们还使用了 glimpse,但无法深入了解该过程。

结果类型不是模型中的实体,因此我们确信不涉及跟踪。

我们也知道这不是针对上下文执行的第一个查询,因此我们不会为此查询支付 EF 启动成本。

我们尝试了 .net 分析器,但在运行它时遇到了很多问题,所以我们决定直接询问。

关于如何挖掘和解决这个问题的任何提示?

编辑:此查询的结果集是 1 行 4 列(十进制)

这行代码就是:

var list=contextInstance.Database.SqlQuery<nonEntityType>(sqstring).ToList();

SQL 本身并不是一个很长的字符串。我们将使用更详细的分析器来找出进程中挂起的位置。

【问题讨论】:

  • 我能想象的唯一一件事是,大量的数据在网络上传输,创建结果列表/数组/无论您正在处理什么结果都需要时间。这不是以 SQL 执行时间来衡量的
  • @DavidLeitner 我认为这不是索引* 问题,因为查询本身在 SQL Server 中执行得非常快。所以这是在查询被推入数据库之前或在出路之前的事情。没有一个 LINQ 查询显示出这种差异。 db 执行时间和完整的 EF 查询执行时间之间的跨度很小。 *我也一直想说指数! :) 永远不知道哪个是正确的! :)
  • 你是using上下文吗?你可以试试。此外,如果您不打算更新数据,您也可以尝试AsNoTracking()。哦,咔嚓。这不是DbSet。您能否将更多代码粘贴到问题中,例如 SQL 字符串和一些周边代码?在干净的上下文(使用 using)上尝试相同的查询,就像在单元测试中一样。
  • 涉及多少数据?你是什​​么时间?我们可以看到一些代码吗?您使用的是什么提供商?您使用的是什么连接协议?这是 SQL Server 吗?您传递给类型参数的类型是什么样的?它在它的构造函数中做任何事情吗?你能用原始 ADO.net 代码尝试它到数据阅读器并填充你的类型,这将排除网络/协议问题。
  • 使用 Intellitrace(在 VS Enterprise/Ultimate 中)

标签: c# .net entity-framework visual-studio-2013 profiling


【解决方案1】:

我们使用 EF 分析器发现了这一点,我们还运行了 SQL 直接在 SQL Server Management Studio 中,它是即时的。

这并不能证明什么。查询可能运行得很快,但数据可能会产生 100MB 的数据,然后将其传输到客户端并在对象中具体化。这可能需要比您想象的更多的时间。

SSMS 中的查询可能会立即返回,因为它只显示部分数据。你没有说数据是什么。

使用真正的 .NET 分析器,例如 dotTrace 或 Ants。通过这种方式,您可以准确地看到时间在哪里丢失。 EF Prof(或我自己的 ORM Profiler:http://www.ormprofiler.com)会告诉您所采用的总路线的哪一部分(ORM->DB->ORM)需要什么时间。甚至 EF 教授都这样做;)

【讨论】:

  • OP 跟进了这样一个事实,即结果集是 1 行,有 4 个标量十进制列。它很小。他还写道:“我正在调用 DbContext.Database.SqlQuery,数据库部分需要 3 毫秒,但完整执行需要 9 秒。我们使用 EF Profiler 来发现这一点” EF Prof 显示完整 RT 为 9 秒,但db 部分只有几毫秒。我们花了很多时间与 VS 的分析器(我自己经常使用它)作斗争,试图更深入地了解瓶颈代码可能在哪里。在这里问,希望避免更多的时间浪费。 ORMP 是否比上下文调用和数据库查询显示更多细节?
  • 它将显示从 con Open 到 con close 哪个部分花费了哪些时间和调用堆栈。如果连接打开状态需要 9 秒,则 EF 有问题,但 EF prof 也会告诉你。 vs'分析器,算了。使用 dotTrace 或 ant,它会告诉你哪条线花了什么时间。需要 10 秒。
【解决方案2】:

如果客户由于某种原因无法使用 Frans 建议的分析器,您将不得不玩猜谜游戏并排除可能性。

首先,我认为缺少一条关键信息。它总是需要大约 9 秒还是有所不同?

第一步:

决定延迟是在查询到达数据库之前还是之后。应该可以使用 EF 探查器并查看 Sql 探查器中的时间戳。

无论哪种方式,您都会稍微限制一下可能性。

第二步:

尽可能排除

  • 索引(不,查询很快)
  • 返回的数据过多(不,根据您的信息)
  • 查询编译慢(否,使用原始 sql 查询)
  • 数据传输缓慢(不,其他查询运行良好)
  • DbContext 初始化慢(不,你说这不是第一次查询)
  • 行或表锁(不太可能,这可能会在分析器中显示为长时间运行的查询)
  • 实现缓慢(不,只有少数字段,除非存在严重的边缘情况错误)

第三步:

还剩下什么?这取决于#1 的答案以及是否总是 9 秒。

我在这里的主要怀疑是一些连接问题,因为另一个调用被阻塞,所以它必须等待连接或一些二级缓存,或者这个查询不能很好地工作。

为了排除更多替代方案,我会尝试使用普通的旧 ADO.NET 运行相同的查询。如果问题仍然存在,您就知道这不是 EF 问题,很可能是连接问题。如果它消失了,它仍然可能是两个问题。

与其说是一些咆哮,不如说是一个答案,但希望是你还没有想到的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-22
    • 1970-01-01
    相关资源
    最近更新 更多