Когда я должен использовать CompiledQuery? - PullRequest
21 голосов
/ 08 февраля 2011

У меня есть таблица:

-- Tag

ID  | Name
-----------
1   | c#
2   | linq
3   | entity-framework

У меня есть класс, который будет иметь следующие методы:

IEnumerable<Tag> GetAll();
IEnumerable<Tag> GetByName();

Должен ли я использовать скомпилированный запрос в этом случае?

static readonly Func<Entities, IEnumerable<Tag>> AllTags =
    CompiledQuery.Compile<Entities, IEnumerable<Tag>>
    (
        e => e.Tags
    );

Тогда мой GetByName метод будет:

IEnumerable<Tag> GetByName(string name)
{
    using (var db = new Entities())
    {
        return AllTags(db).Where(t => t.Name.Contains(name)).ToList();
    }
}

, который генерирует SELECT ID, Name FROM Tag и выполняет Where в коде. Или я должен избегать CompiledQuery в этом случае?

По сути, я хочу знать, когда мне следует использовать скомпилированные запросы. Кроме того, на веб-сайте они составляются только один раз для всего приложения?

Ответы [ 5 ]

28 голосов
/ 08 февраля 2011

Вы должны использовать CompiledQuery, когда выполняются все следующие условия:

  • Запрос будет выполнен более одного раза, варьируя только значениями параметров.
  • Запросдостаточно сложен, так что стоимость оценки выражения и создания представления является «значительной» (методом проб и ошибок)
  • Вы не используете функцию LINQ, такую ​​как IEnumerable<T>.Contains(), которая не будет работать с CompiledQuery.
  • Вы уже упростили запрос, что дает большее преимущество в производительности, когда это возможно.
  • Вы не собираетесь дополнительно составлять результаты запроса (например, ограничить или проект), что имеет эффект«декомпилируя» его.

CompiledQuery выполняет свою работу при первом выполнении запроса.Это не дает никакой выгоды для первого исполнения.Как и при любой настройке производительности, обычно избегайте ее, пока не убедитесь, что исправляете фактическую точку производительности.

2012 Обновление: EF 5 сделает это автоматически (см. « Entity Framework 5: Управление автоматической компиляцией запроса »).Поэтому добавьте «Вы не используете EF 5» в приведенный выше список.

6 голосов
/ 08 февраля 2011

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

В вашем случае, если вы уверены, что он сгенерирует SELECT ID, Name FROM Tag без случая WHERE (в чем я сомневаюсь, так как ваша AllQueries функция должна возвращать IQueryable и фактический запрос должен быть выполнен только после вызова ToList) - вы не должны его использовать.

Как уже упоминалось, для больших таблиц SELECT * FROM [someBigTable] займет очень много времени, и вы потратите еще больше времени на фильтрацию на стороне клиента. Поэтому вам следует убедиться, что ваша фильтрация выполняется на стороне базы данных, независимо от того, используете ли вы скомпилированные запросы или нет.

1 голос
/ 08 февраля 2011

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

0 голосов
/ 08 февраля 2011

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

Но я бы не стал использовать его для всех запросов, поскольку это немного больше кода для написания, а для простых запросов это может не стоить.

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

0 голосов
/ 08 февраля 2011

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

...