我有一个linq查询需要几秒钟(~2.6秒)才能运行。但我希望尽可能少地减少它。
我只需要阅读,所以我已经包含了.AsNoTracking()行为。
我还测试了没有include语句的查询,但是我的操作在get请求之后进一步减慢了速度,所以我离开了包含来优化我的其他操作。
主要目标是减少数据库通话,因此ToList(),Include语句。
代码:
var obj = _context.MyContextModel.AsNoTracking()
.Where(x => x.CategoryList.Model.Id == 1)
.Where(x => x.CategoryList.Model.TypeId == 1)
.Where(x => x.Year.Select(y=>y.Datetime).Any(item => item.Year == 2010))
.Include(x => x.LinkedMarket).AsNoTracking()
.Include(x => x.Year).AsNoTracking()
.Include(x => x.CategoryList).AsNoTracking()
.Include(x => x.CategoryList.Model).AsNoTracking();
return obj.AsParallel().ToList();
此操作通常会返回大约1000-2000个MyContextModel记录,不包括" includes"
如何进一步优化? 我应该将对象加载到容器类吗?或另一种解决方案?
更新
_context.Configuration.ProxyCreationEnabled = false;
_context.Configuration.LazyLoadingEnabled = false;
var obj = _context.MyContextModel.AsNoTracking()
.Where(x => x.CategoryList.Model.Id == 1)
.Where(x => x.CategoryList.Model.TypeId == 1)
.Where(x => x.LinkedMarket.FirstOrDefault(mar=>mar.MarketID == marketId) != null)
.Include(x => x.Year).AsNoTracking()
.Include(x => x.CategoryList).AsNoTracking()
.Include(x => x.CategoryList.Model).AsNoTracking();
return obj.AsParallel().ToList();
基本上我已经删除过滤年份的where子句(我之后会这样做,因此包含年份) 我添加了一个Where子句,用于从getgo中指定市场。
我已删除包含市场的Include。
一个大的表现小偷是关联市场(我不知道为什么,EF不喜欢的东西。)
这将查询缩小到大约0.4秒的平均值。 整个操作设置从4秒到惊人的0.7秒。
答案 0 :(得分:2)
您执行的每个包含都将最终在数据库中执行连接。 假设您的左表是非常大的1024字节的记录大小,并且您有许多细节,比如1000,并且详细记录大小只有100。 这将导致左表的信息重复1000次,这些信息将由db放在线上,EF必须过滤掉重复的内容以创建左实例。
最好不要使用include并进行显式加载。基本上在同一个上下文中执行2个查询。
我有一个使用以下原理的例子。它可以比依赖包含快10倍。 (数据库只能有效地处理有限数量的连接)
var adressen = adresRepository
.Query(r => r.RelatieId == relatieId)
.Include(i => i.AdresType)
.Select().ToList();
var adresids = (from a in adressen select a.AdresId).ToList();
IRepositoryAsync<Comm> commRepository = unitOfWork.RepositoryAsync<Comm>();
var comms = commRepository
.Query(c => adresids.Contains(c.AdresId))
.Include(i => i.CommType)
.Select();
对于commType和adresType,我使用include,因为存在1对1的关系,我避免了太多的连接,因此我的多个查询将比使用include的单个查询更快。我没有在第一个查询中包含Comms来尝试避免第二个查询,重点是在这种情况下2个查询比单个查询更快。
最重要的是要考虑的不仅仅是避免延迟加载,还需要考虑哪些包含需要而哪些不需要。您可能需要该信息,并且包含快速简便,但在同一上下文中的额外查询可以更快。