优化entity framework查询,避免延迟加载

我有一个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记录,不包括“包含”

我该如何进一步优化? 我应该将对象加载到容器类吗? 或其他解决方案?

更新

 _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秒。

每个包含你最终将在数据库中执行连接。 假设您的左表是非常大的1024字节的记录大小,并且您有许多详细信息,比如1000,并且详细记录大小只有100.这将导致左表的信息重复1000次,此信息将由数据库放在线上,EF必须过滤掉重复的数据以创建您的左实例。

最好不要使用include并进行显式加载。 基本上在同一个上下文中执行2个查询。

我有一个使用下面这个原理的例子。 它可以比依赖包含快10倍。 (db只能有效地处理有限数量的连接)

 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 commRepository = unitOfWork.RepositoryAsync(); var comms = commRepository .Query(c => adresids.Contains(c.AdresId)) .Include(i => i.CommType) .Select(); 

对于commType和adresType我使用include因为有一对一的关系,我避免了太多的连接,因此我的多个查询将比使用include的单个查询更快。 我没有在第一个查询中包含Comms来尝试避免第二个查询,重点是在这种情况下2个查询比单个查询更快。

最重要的是要考虑的不仅仅是避免延迟负载,还需要考虑哪些包含需要哪些不需要。 您可能需要该信息,并且包含快速简便,但在相同上下文中的额外查询可以更快。