【发布时间】:2015-04-26 08:21:59
【问题描述】:
我有一个 linq 查询需要几秒钟(~2.6 秒)才能运行。但我想尽量减少。
我只需要阅读,所以我已经包含了 .AsNoTracking() 行为。
我还测试了没有包含语句的查询,但是我在获取请求后的操作进一步减慢了它,所以我留下了包含以优化我的其他操作。
主要目标是减少数据库对话,因此 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 子句,从一开始就指定市场。
我已删除包含市场的包含。
链接市场是一个大的性能窃贼(我不知道为什么,这是 EF 不喜欢的东西。)
这将查询减少到大约平均 0.4 秒。 整个操作从 4+ 秒到惊人的 0.7 秒。
【问题讨论】:
-
您是否在 SSMS 中分析了生成的查询以查找缺失索引等?
-
某事告诉我问题就在那里。Where(x => x.Year.Select(y=>y.Datetime).Any(item => item.Year == 2010))
-
@ErikEJ 。我无法控制数据库,所以无论如何我都无法更改任何内容。
-
你有很多
AsNoTracking()。尝试使用_context.Configuration.ProxyCreationEnabled = false;。Include(x => x.CategoryList.Model)没用。使用Include("CategoryList.Model")。否则,实现是有代价的。 -
您需要所有列吗?您可以通过预测获得很多收益。
标签: c# performance linq entity-framework