【问题标题】:Entity Framework 6.2 database first warm upEntity Framework 6.2 数据库先预热
【发布时间】:2019-02-13 13:42:52
【问题描述】:

我的 MVC 解决方案中有一个 EF 6.2 项目。

这使用了一个 SQL 服务器数据库,并且有大约 40 个带有许多外键的表。

第一次查询很慢,20秒。

我立即再次点击同一页面,更改用户参数,查询时间不到 1 秒。

所以这看起来像是 EF6 中的一个预热问题。没关系,我可以做很多事情来进行排序。

  1. 模型缓存(EF6.2 的一部分)看起来可能是有益的,但我读到的任何地方都首先声明模型。首先没有关于数据库的内容。这仍然可以先使用 db 吗?
  2. 还有 Entity Framework 6 电动工具,这些工具允许我生成视图。试过这个,它似乎没有任何区别。这仍然是一条有效的路线吗?
  3. 还有其他想法吗?

【问题讨论】:

  • 查询是否是服务器需要编译的SP(可能带有重新编译选项)?它只是第一次还是总是具有特定的价值?加速可能是数据库从磁盘检索数据,如果内容已经缓存,则以下可能会很快。它真的是数据库还是可能是另一个 MVC 资源?
  • 它是实体框架,根本没有使用任何 SP。总是在发布后的第一次,或者如果网站已经有一段时间了。
  • 谢谢,是的,我已经读过了,但它没有回答我提出的两个主要问题。
  • 我想知道查询有多复杂?它有很多包含吗?我发现从初始查询中取出包含然后单独调用它们可以显着提高性能,尤其是在应用重启后。

标签: sql-server entity-framework warm-up


【解决方案1】:

EF DbContext 会产生一次性成本来解析其实体映射。对于 Web 应用程序,您可以通过让应用程序启动启动针对 DbContext 的简单查询来缓解这种情况,该查询“启动”此热身,而不是在您的第一个用户触发查询期间。简单地新建一个上下文不会触发初始化,运行查询会。所以对于Application_Start 上的 ASP.Net MVC,在初始化一切之后:

using (var context = new MyContext())
{
   var warmup = context.MyTable.Count(); // against a small table.
}

您可以使用一组从 DbContext 读取数据的定时测试并在 DbContext 的 OnModelCreating 事件中设置断点,从而使用单元测试来测试此行为。它将在第一个查询的第一个测试中执行一次。您可以在测试夹具设置中添加OneTimeSetUp,以便在使用上述快速计数示例的测试之前运行,以便在测量测试运行的性能之前产生此成本。

【讨论】:

    【解决方案2】:

    所以,答案是将 EF 更新到 6.2,然后使用最新功能:

    public class MyDbConfiguration : DbConfiguration
    {
        public MyDbConfiguration() : base()
        {
            var path = Path.GetDirectoryName(this.GetType().Assembly.Location);
            SetModelStore(new DefaultDbModelStore(path));
        }
    }
    

    要查看完整故事,请查看此链接:https://entityframework.net/why-first-query-slow

    您会在启动时对性能造成小幅影响,但随后一切都会变得更快。

    对于使用 Azure Web 应用程序的任何人,您都可以使用部署槽 (https://stackify.com/azure-deployment-slots/),这允许您发布到非生产槽,然后在将其作为生产槽换入之前对其进行预热。

    【讨论】:

      猜你喜欢
      • 2013-06-13
      • 2016-03-31
      • 2020-02-29
      • 1970-01-01
      • 2018-08-14
      • 2013-07-10
      • 1970-01-01
      • 2013-09-23
      • 1970-01-01
      相关资源
      最近更新 更多