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

Когда следует использовать CompiledQuery?

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

-- 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 в этом случае?

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

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

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