Является ли несколько операторов Where () в LINQ проблемой производительности?

18

Мне интересно, есть ли последствия для нескольких операторов Where (). Например, я мог бы написать:

var contracts =  Context.Contract
    .Where(
        c1 =>
            c1.EmployeeId == employeeId
        )
    .Where(
        c1 =>
            !Context.Contract.Any(
                c2 =>
                    c2.EmployeeId == employeeId
                    && c1.StoreId == c2.StoreId
                    && SqlFunctions.DateDiff("day", c2.TerminationDate.Value, c1.DateOfHire.Value) == 1
                )
        )
    .Where(
        c1 =>
            !Context.EmployeeTask.Any(
                t =>
                    t.ContractId == c1.Id
                )
        );

Или, в качестве альтернативы, я мог бы объединить их все в одно предложение Where (), например:

var contracts =  Context.Contract
    .Where(
        c1 =>
            c1.EmployeeId == employeeId
            && !Context.Contract.Any(
                c2 =>
                    c2.EmployeeId == employeeId
                    && c1.StoreId == c2.StoreId
                    && SqlFunctions.DateDiff("day", c2.TerminationDate.Value, c1.DateOfHire.Value) == 1
                )
            && !Context.Employee_Task.Any(
                t =>
                    t.ContractId == c1.Id
                )
        );

Оказывает ли цепь предложения Where () повреждение производительности или эквивалентны?

    
задан John 19.01.2011 в 14:01
источник
  • Я думаю, что LINQ компилируется как к аналогичному выражению, независимо от того, как вы его создаете (если вы не вызываете ToList () или сортировку где-то между «Где», –  sinelaw 19.01.2011 в 14:06

1 ответ

16

В LINQ to Objects будет очень небольшой удар производительности, потому что в основном цепочка итераторов будет длиннее - выборка следующего элемента означает увеличение длинной цепи вызовов MoveNext ().

В LINQ to SQL и подобных провайдерах я ожидаю, что один и тот же SQL будет сгенерирован в любом случае, поэтому он не повлияет на производительность там.

EDIT: после написания этого я узнал немного больше о реализации LINQ to Objects - это немного сложнее ...

    
ответ дан Jon Skeet 19.01.2011 в 14:05
  • Все верно. Большое спасибо. Я не знаю, лучший ли пример, но иногда мне кажется, что мне будет легче читать и понимать некоторые запросы, если я свяжусь с несколькими операторами, которые не имеют ничего общего друг с другом. / John –  John 19.01.2011 в 14:32
  • @ Если вы правильно поняли, то для объектов есть вероятность для оптимизации в соответствии с порядком предложений where (чего в SQL не существует, так как оптимизатор делает это для вас)? Я полагаю, что в LINQ-to-Entities оптимизация также обрабатывается фоновым контентом? –  ekkis 02.09.2011 в 22:00
  • @ekkis: Да; если вы поместите дешевый фильтр, который сначала избавится от большинства элементов-кандидатов, это ускорит процесс. –  Jon Skeet 02.09.2011 в 22:04
  • @Jon, для тех, кто больше привык иметь оптимизатора, это действительно полезно знать. благодаря! (вы получаете всплеск) –  ekkis 07.09.2011 в 01:10
  • @Jeff: Исправлено, спасибо. –  Jon Skeet 02.03.2015 в 07:45