非常慢的IOrderedQueryable ToList()

时间:2012-12-18 07:09:04

标签: c# linq entity-framework

我的查询返回带有过滤子项的父项:

 Context.ContextOptions.LazyLoadingEnabled = false;
  var query1 = (from p in Context.Partners
                          where p.PartnerCategory.Category == "03"
                                || p.PartnerCategory.Category == "02"
                          select new
                                     {
                                         p,
                                         m = from m in p.Milk
                                             where m.Date >= beginDate
                                                   && m.Date <= endDate
                                                   && m.MilkStorageId == milkStorageId
                                             select m,
                                         e = p.ExtraCodes,
                                         ms = from ms in p.ExtraCodes
                                              select ms.MilkStorage,
                                         mp = from mp in p.MilkPeriods
                                              where mp.Date >= beginDate
                                                    && mp.Date <= endDate
                                              select mp
                                     }).Where(
                                         p =>
                                         p.p.ExtraCodes.Select(ex => ex.MilkStorageId).Contains(
                                             milkStorageId) ).OrderBy(p => p.p.Name);
 var partners = query1.AsEnumerable().ToList();

查询返回200条记录并从IOrderedQueryable ToList()转换非常慢。为什么呢?

在sql server management studio中分析查询后,我注意到查询执行1秒并返回2035条记录。

3 个答案:

答案 0 :(得分:1)

它很慢的原因是因为当你执行ToList时,就是实际执行查询的时间。这称为deferred execution

您可能会看到:LINQ and Deferred Execution

我认为您在将其转换为列表时不需要AsEnumerable,您可以直接执行此操作:

var partners = query1.ToList();

答案 1 :(得分:1)

这可能有很多原因,没有任何探查器信息,它只是猜测工作,甚至高度教育的猜测工作,知道代码和域很好的人经常是错误的。

您应该对代码进行概要分析,因为可能是数据库中的瓶颈可能会获得@Likurg建议的命令文本并在数据库中对其进行概要分析。您可能缺少一个或多个索引。

你可以对自己的查询做一些事情,如果没有别的东西可以让它更容易理解,可能更快

E.g。

p.p.ExtraCodes.Select(ex => ex.MilkStorageId).Contains(milkStorageId)

真的是

p.p.ExtraCodes.Any(ex => ex.MilkStorageId == milkStorageId)

并且可以移动到第一个where子句可能,从而降低您创建的匿名类型对象的数量。也就是说,最可能的情况是你在比较中使用的许多字段中的一个字段没有索引,可能导致结果集中每个元素的大量表扫描。

索引可能加快速度的一些领域是

  • p.p.Name
  • m.Date
  • m.MilkStorageId
  • mp.Date
  • PartnerCategory.Category

答案 2 :(得分:0)

首先,使用此

查看生成的查询
Context.GetCommand(query1).CommandText;

然后在db中调用此命令。并检查分析器读取的记录数。