【发布时间】:2016-01-18 21:56:26
【问题描述】:
我正在优化我们的 Entity Framework 代码,目前我遇到了一个不知道如何解决的问题。
我们正在使用 Azure SQL + 代码优先实体框架 6.1.3 + Asp.net Web Api v2。端点托管在云端,我正在使用它进行测试。
我有一个 API 操作,用于获取过滤、排序和分页的数据。这是我处理数据的简化代码:
var entities = DbContext.Services
.Include(q => q.Consumer.Building.Address.Country)
.Include(q => q.Consumer.Building.Address.State);
entities = entities.OrderBy(x => x.Consumer.RegisteredAt);
entities = entities.Where(x => x.IsDeleted == false);
entities = entities.Where(x => userId.HasValue ? x.Owner.Id == userId ? true); //this part comes from deep internals, so I cannot change it quickly
var page = entities = entities.Skip(skip).Take(take).ToList();
var count = entities.Count();
var dtoPage = Mapper.Map<IEnumerable<ServiceDto>>(page);
return Page<ServiceDto>(dtoPage, count);
所以代码没有什么特别之处——不使用IN 子句等,只是简单的过滤、排序和分页。
问题: 调用此方法执行时间不稳定。我使用了一个简单的脚本来调用 API 端点,该端点使用不同的参数调用此代码:它依次获取 0..5 页 200 次。对于每个呼叫(第一个呼叫除外),我预计呼叫时间少于 300 毫秒。 但是:在 1200 次调用中,有 36 次调用时间超过了 1 秒 - 就像在此期间再次重新编译了查询一样。平均调用时间为 250ms,但有时会飙升至 1000ms,相差 4 倍。
测试的常见行为是:
第一次查询很慢
第二次查询更快,但仍然比休息慢
除了不时出现的峰值之外,其余查询非常稳定。
除了我之外没有人使用过测试环境,所以这不是负载问题,我可以在任何环境中重现它,即使是在快速的本地 PC - i5 + 8gb RAM + SSD 上。
测试之间的延迟也很小 -
所以简而言之,我的问题是: 这个问题是怎么来的?
- 这真的是重新编译问题吗?如果不是,问题的可能根源是什么?
- 是否有关于 Entity Framework 6 的查询缓存失效的文档?
- 有没有办法让查询在缓存中保留更长的时间,这样如果我现在和 30 分钟后查询该方法,它就不必重新编译它?
【问题讨论】:
-
根据Rewriting a LINQ Expression query to enable caching SQL Execution Plan和里面的链接主题,可能是因为分页(
Skip和Take)。看看提到的重载对你的情况是否有帮助。
标签: c# entity-framework azure entity-framework-6 azure-sql-database