LINQ - Используя где или соединение - Различие в производительности?

На основе этого вопроса: Что такое различие между тем, Где и Участвуют в linq?

Мой вопрос следует:

Есть ли в следующих двух операторах различие в производительности:

from order in myDB.OrdersSet
    from person in myDB.PersonSet
    from product in myDB.ProductSet
    where order.Persons_Id==person.Id && order.Products_Id==product.Id
    select new { order.Id, person.Name, person.SurName,  product.Model,UrunAdı=product.Name };

и

from order in myDB.OrdersSet
    join person in myDB.PersonSet on order.Persons_Id equals person.Id
    join product in myDB.ProductSet on order.Products_Id equals product.Id
    select new { order.Id, person.Name, person.SurName,  product.Model,UrunAdı=product.Name };

Я всегда использовал бы второй просто, потому что это более ясно.

Мой вопрос теперь, первый медленнее, чем второй? Это создает cartesic продукт и фильтрует его впоследствии с где пункты?

Спасибо.

5
задан Community 23 May 2017 в 12:13
поделиться

2 ответа

Это полностью зависит от провайдера, которого вы используете.

LINQ to Objects полностью построит декартово произведение и затем отфильтрует его.

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


Примечание: несколько предложений «from» не всегда приводят к декартовому произведению - содержимое одного «from» может зависеть от текущего элемента более ранних, например

from file in files
from line in ReadLines(file)
...
3
ответ дан 15 December 2019 в 00:51
поделиться

У меня вопрос, первый медленнее второго? Создает ли он картезный продукт, а затем фильтрует его с помощью предложений where?

Если коллекции находятся в памяти, , тогда да . Оптимизатора запросов для LinqToObjects нет - он просто выполняет то, что просит программист, в том порядке, в котором его просят.

Если коллекции находятся в базе данных (что подозревается из-за переменной myDB), , то нет . Запрос переводится в sql и отправляется в базу данных, где есть оптимизатор запросов. Этот оптимизатор сгенерирует план выполнения. Поскольку оба запроса запрашивают один и тот же логический результат, разумно ожидать, что для обоих будет сгенерирован один и тот же эффективный план. Единственный способ быть уверенным - это

  • проверить планы выполнения
  • или измерить IO (SET STATISTICS IO ON).

Есть ли разница в производительности?

Если вы попадаете в ситуацию, когда вам нужно спросить, вам следует развивать инструменты, с помощью которых вы сможете измерять и открывать для себя правду. Измерьте - не просите.

1
ответ дан 15 December 2019 в 00:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: