实体框架第一次查询比第二次慢得多

Posted

技术标签:

【中文标题】实体框架第一次查询比第二次慢得多【英文标题】:Entity Framework first query is much slower than second 【发布时间】:2020-12-03 08:25:26 【问题描述】:

在我的网站中,我使用 ASP.NET MVC 5 和 EF6。

我的性能很慢,第一次调用只有 2 万条记录。

例如,我需要从Person 表中获取所有行。

第一次调用:7500 毫秒(之后在第二行只需要 1000 毫秒)

List<Person> persons = await _context.Person.ToListAsync(); // Time : 7500ms
List<Person> persons2 = await _context.Person.ToListAsync(); // Time : 1000ms

我尝试了什么:

取消了 edmx 架构的延迟加载 刷新架构

SQL Server Management Studio 中的相同查询需要 400 毫秒(这是一个非常简单的查询,没有连接和条件)

每次客户访问个人页面时都会发生这种情况

【问题讨论】:

它产生的 SQL 是什么?你可以打开日志/sql调试(我忘记了如何,但它是单行的,应该很容易找到) 代码必须 JIT 并且映射也可能会被检查。如果数据库缓存查询计划作为结果,数据库也可以发挥作用(您可以使用 Profiler 看到)。 是的,对上下文对象的第一次调用将运行所有模型构建器并从本质上验证设置,这是一个成功,(但不应该是 7.5 秒的命中..) 可能与Entity framework very slow to load for first time after every compilation、***.com/questions/10757019、***.com/q/9261095/270591和***.com/q/11543990/270591相关 @Igor 我认为它是某种内部缓存,可以看到它是同一个查询,但是第一次会花费这么多时间(试图刷新 edmx)但什么都没有.. 【参考方案1】:

我会在评论中发布此内容,但它太长了。

有很多因素会影响该时差,按照可能性/影响较小到可能性/影响较大的顺序排列:

第一个查询,一旦在 SQL Server 中(如果那是底层引擎)有时必须“预热”SQL。我怀疑这是实际问题,因为 SQL Server 可能没有足够的时间在您的尝试之间“关闭”。此外,对于 that 查询,执行计划应该不会有太大问题。 第一个查询必须打开通信通道。例如,如果它必须通过 *** 进行路由,或者只是打开 SQL 连接,则会增加延迟。 迁移:除非您手动强制迁移,否则当您创建 DbContext 时,EF6 不会在此时运行迁移(和播种)。它等待第一次实际需要查询,然后构建配置并执行迁移。

如果要进行调查,请在 OnModelCreating 方法中放置一个断点,然后查看它何时被调用。您还可以在这两个查询之前添加另一个查询到一个不相关的实体,您会发现它不是因为缓存(AFAIK,缓存仅在使用 DbSet&lt;T&gt;.Find(...) 时使用)

【讨论】:

我使用数据库优先方法,在我的上下文中,未实现 OnModelCreating 方法 throw new UnintentionalCodeFirstException(); 好吧,如果你愿意,你可以在你的第一个请求之前添加一个断点,检查 SQL Trace,看看它还没有连接。

以上是关于实体框架第一次查询比第二次慢得多的主要内容,如果未能解决你的问题,请参考以下文章

使用参数化查询时,TVF 慢得多

实体框架首先访问数据库

为啥函数第一次调用比第二次和第三次调用花费更多的时间等等?

存储过程和实体框架的性能

为啥子查询中的 OR 会使查询慢得多?

为啥 BufferedReader read() 比 readLine() 慢得多?