问题描述
在我的网站中,我使用的是带有EF6的ASP.NET MVC 5。
我第一次拨打电话只有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 Server中(如果这是基础引擎),有时必须“预热” SQL。我怀疑这是实际的问题,因为SQL Server可能没有足够的时间在两次尝试之间“停机”。而且,执行计划对于那个查询来说应该不会有太大问题。
- 第一个查询必须打开通信通道。例如,如果必须通过VPN进行路由,或者只是打开SQL连接,则会增加延迟。
- 迁移:除非手动执行迁移,否则在创建
DbContext
时,EF6当时不会运行迁移(和播种)。它会在第一次真正需要查询时等待,然后构建配置并执行迁移。
如果要调查,请在OnModelCreating
方法中放置一个断点,并查看何时调用它。您还可以在这两个查询之前将另一个查询添加到一个不相关的实体,这将不是因为缓存(AFAIK,仅在使用DbSet<T>.Find(...)
时才使用缓存)