【问题标题】:Optimising Lambda Linq to SQL query with OrderBy使用 OrderBy 优化 Lambda Linq to SQL 查询
【发布时间】:2010-07-02 11:09:10
【问题描述】:

我有以下 lambda 表达式:

IEnumerable<Order> query
       = _ordersRepository.GetAllByFilter(
            o => 
                o.OrderStatus.OrderByDescending(os => os.Status.Date).First()
                    .Status.StatusType.DisplayName != "Completed"
                ||   
                o.OrderStatus.OrderByDescending(os => os.Status.Date).First()
                    .Status.Date > sinceDate
         ).OrderBy(o => o.DueDate);

如您所见,我必须在主查询中对集合进行两次排序(总共 3 次)才能执行我的 OR 查询。

1) 查询优化器是否足够聪明,可以有效地处理这个问题?

2) 如果不是,我如何将这个表达式重写为仅按一次排序,但保持 lambda 语法

链接到this previous question,如果上面的代码不清楚,它会更详细地解释查询。

【问题讨论】:

    标签: performance linq-to-sql optimization lambda query-optimization


    【解决方案1】:

    1) 查询优化器是否足够聪明,可以有效地处理这个问题?

    您可以获取此查询的 SQL(一种方法是使用 SQL 分析器),然后向 SQL Studio 询问执行计划。除非您这样做,否则无法知道优化器的想法。我的猜测是答案是否定的。

    2) 如果没有,我该如何重写这个表达式,使其仅按一次排序,但保持 lambda 语法?

    像这样:

    IEnumerable<Order> query = _ordersRepository.GetAllByFilter( o =>
      o.OrderStatus
        .OrderByDescending(os => os.Status.Date)
        .Take(1)
        .Any(os => os.Status.StatusType.DisplayName != "Completed"
          || os.Status.Date > sinceDate)
    })
    .OrderBy(o => o.DueDate); 
    

    【讨论】:

      【解决方案2】:

      关于您的第一点:您可以看到通过订阅 DatabaseContext 对象的输出生成的 SQL。这通常位于名为 Log 的属性中。

      至于优化您的查询,请尝试以下(我没有测试过,所以我不知道它是否有效)

      IEnumerable<Order> query
         = _ordersRepository.GetAllByFilter(
              o =>
                  o.OrderStatus.Max(os => os.Status.Date).Any(os =>
                      os.Status.StatusType.DisplayName != "Completed"
                      || os.Status.Date > sinceDate)
           ).OrderBy(o => o.DueDate);
      

      希望这只会执行一次子查询,并且还会执行最大值而不是前 1 的顺序。

      【讨论】:

      • 我认为 Max 无法做到这一点,它会在该查询中返回 DateTime。
      • 啊,是的,我的错。很高兴大卫 B 在那里 :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-13
      • 1970-01-01
      • 2012-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多