我的MVC解决方案中有一个EF 6.2项目。
这使用一个SQL Server数据库,并具有大约40个带有许多外键的表。
第一次查询非常慢,只需20秒。
我立即再次点击了同一页面,更改了用户参数,查询时间不到1秒。
因此,这看起来像是EF6中的预热问题。很好,很显然我可以做很多事情。
答案 0 :(得分:1)
EF DbContext花费一笔一笔费用来解决其实体映射。对于Web应用程序,您可以通过让应用程序启动针对DbContext的简单查询来缓解这种情况,该查询会“启动”预热,而不是在您的第一个用户触发的查询期间启动。只需新建一个上下文就不会触发初始化,运行查询会触发初始化。因此,对于imapClient.SelectMailbox("INBOX");
SearchCondition condition = new SearchCondition();
condition.Field = SearchCondition.Fields.Since;
condition.Value = new DateTime(2019, 2, 12).ToString("dd-MMM-yyyy");
var messages = imapClient.SearchMessages(condition);
上的ASP.Net MVC,在初始化所有内容之后:
Application_Start
您可以通过进行一组定时测试以从DbContext读取数据,并在DbContext的using (var context = new MyContext())
{
var warmup = context.MyTable.Count(); // against a small table.
}
事件中放置一个断点,来使用单元测试来测试此行为。从第一个测试到第一个查询,它将仅执行一次。您可以在测试夹具设置中添加OnModelCreating
,以使用上述快速计数示例在测试之前运行,以在测量测试运行的性能之前产生此费用。
答案 1 :(得分:0)
因此,答案是将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/),这允许您将其发布到非生产槽中,然后对其进行预热,然后再将其替换为生产槽。