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

Мне интересно, есть ли последствия для производительности нескольких операторов .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() на производительность или они эквивалентны?


person John    schedule 19.01.2011    source источник
comment
Я думаю, что LINQ компилирует оба в похожее выражение, независимо от того, как вы его строите (пока вы не вызываете ToList() или сортируете где-то посередине «Где»)   -  person sinelaw    schedule 19.01.2011


Ответы (1)


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

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

РЕДАКТИРОВАТЬ: с момента написания этого я узнал немного больше о реализации LINQ to Objects - это немного сложнее...

person Jon Skeet    schedule 19.01.2011
comment
Отлично. Спасибо большое. Я не знаю, является ли этот пример лучшим, но иногда я думаю, что мне будет легче читать и понимать некоторые запросы, если я свяжу несколько операторов where, которые не имеют ничего общего друг с другом. /Джон - person John; 19.01.2011
comment
@Jon, если я правильно тебя понял, для объектов есть возможность оптимизации в соответствии с порядком предложений where (чего в SQL не существует, поскольку оптимизатор делает это за вас)? Я предполагаю, что в LINQ-to-Entities оптимизация также обрабатывается серверной частью? - person ekkis; 03.09.2011
comment
@ekkis: Да; если вы поставите дешевый фильтр, который сначала избавится от большинства элементов-кандидатов, это сильно ускорит процесс. - person Jon Skeet; 03.09.2011
comment
@Jon, для тех, кто больше привык к оптимизатору, это действительно полезно знать. Спасибо! (Вы получаете всплеск) - person ekkis; 07.09.2011