Подтвердить что ты не робот

Когда компиляция запросов LINQ to SQL повышает производительность

Я имел в виду статью, в которой основное внимание уделяется ускорению LINQ to SQL Queries. Один из методов, который он упоминает, - "Использовать скомпилированные запросы" и объясняет, как его использовать.

Я хотел видеть улучшение производительности скомпилированных запросов, и поэтому я попробовал тот же пример, предоставленный автором. Я использовал Northwind Db как datacontext. Я попробовал выполнить обычное выполнение и выполнил компиляцию и проверил их на LINQ PAD.

Сначала я попытался выполнить запрос без с помощью CompileQuery. Это заняло 2.065 секунды.

var oo =   from o in Orders
   where o.OrderDetails.Any (p => p.UnitPrice > 100)
   select o;

oo.Dump ("Order items with unit price more than $100");

var oo1 = from o in Orders
   where o.OrderDetails.Any (p => p.UnitPrice > 10)
   select o;

oo1.Dump ("Order items with unit price more than $10"); 

Во-вторых, запросы с с помощью CompileQuery. Это заняло 2.100 секунд.

var oo = CompiledQuery.Compile ((TypedDataContext dc, decimal unitPrice) =>    
   from o in Orders
   where o.OrderDetails.Any (p => p.UnitPrice > unitPrice)
   select o
);

oo (this, 100).Dump ("Order items with unit price more than $100");
oo (this, 10).Dump ("Order items with unit price more than $10");

Повторное выполнение их несколько раз показало, что время, затраченное обоими подходами, почти одинаково.

Здесь мы видим только два выполнения запросов для каждого метода. Я попытался сделать 10 запросов для каждого из них. Но оба они закончили около 7 секунд.

Действительно ли предварительная компиляция запросов повышает производительность? Или я неправильно понимаю, что это условия использования?

Спасибо за ваше время и внимание.

Edit: После прочтения принятого ответа читатели могут также захотеть пройти в этой статье, в котором приятно объясняется, как скомпилированные запросы повышают производительность.

4b9b3361

Ответ 1

Помните, что есть две основные части запроса LINQ, которые могут быть особенно дорогими:

  • Компилирование выражений LINQ в SQL-выражение.
  • Запуск инструкции SQL и получение результатов

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

Таким образом, по сравнению с количеством времени, которое требуется для создания SQL для вашего запроса (возможно, 10-50 миллисекунд), второй шаг занимает столько времени (~ 1000 мс), что вы вряд ли заметите разницу.

Вы увидите значительные улучшения, если все условия верны:

  • ваш запрос LINQ сложный,
  • у вас есть быстрое соединение с вашей базой данных,
  • сам запрос SQL быстро запускается в этой базе данных и
  • набор результатов достаточно мал, что он быстро возвращается из базы данных.

На практике у меня были запросы, которые могут потребовать от 500 мс для компиляции, но всего несколько миллисекунд для фактического запуска. Обычно это случаи, когда я сосредотачиваюсь на предкомпиляции запросов.

Один из хороших способов заранее узнать, какой рост производительности вы можете ожидать от предварительно скомпилированных запросов, - это время второго экземпляра вашего запроса с использованием объекта Stopwatch, а затем запустить сгенерированный SQL напрямую с помощью функции LINQPad Analyze SQL, Если SQL-запрос возвращается быстро, но запрос LINQ занимает много времени, это хороший кандидат для предварительной компиляции.