Нужны ли нам хранимые процедуры при использовании скомпилированных запросов?

При использовании скомпилированных запросов в структуре сущностей (или linq-to-sql) в сочетании с SQL Server, есть ли еще какое-то преимущество в производительности при использовании хранимых процедур?

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

-- РЕДАКТИРОВАТЬ --

В ответ на ответ Якимыча ниже я не имел в виду, что скомпилированные запросы - это то же самое, что хранимые процедуры. Я пытаюсь выяснить, необходимы ли sprocs, если вы выполнили все возможные оптимизации на стороне приложения (в данном случае скомпилированные запросы). Поэтому я думаю, что я ищу причины, по которым хранимая процедура была бы лучше, чем комбинация оптимизаций на стороне приложения и параметризованных запросов (то, чем эффективно являются скомпилированные запросы).

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

3 ответа

Решение

"Есть ли ситуация, когда хранимые процедуры будут работать значительно лучше?"

При наличии сопоставимого фрагмента параметризованного SQL, сгенерированного либо в EF, либо в хранимом процессе, они будут работать одинаково.

Однако администратор базы данных всегда имеет возможность дополнительно оптимизировать запрос, основываясь на своем опыте работы со схемой базы данных и ее шаблонами использования. Хранимая процедура позволяет им легко делать это изолированно от приложений, использующих ее, а ORM - нет.

У нас есть чрезвычайно сложная БД SQL Server, в которой есть много внешних систем, реплицирующих и выводящих данные через триггеры. Для нас проблема с EF заключается в том, что ответственность за SQL, который запускается в БД, станет ответственностью разработчиков приложений при использовании любого ORM, а не администраторов баз данных.

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

Согласно http://msdn.microsoft.com/en-us/library/cc853327.aspx - при выполнении запроса по концептуальной модели выполняются следующие операции:

  • Загрузка метаданных
  • Открытие соединения с базой данных
  • Генерация просмотров
  • Подготовка запроса
  • Выполнение запроса
  • Загрузка и проверка типов
  • отслеживание
  • Материализация объектов

И объяснение относительно Preparing the query:

Включает затраты на составление команды запроса, создание дерева команд на основе метаданных модели и сопоставления и определение формы возвращаемых данных. Поскольку команды запроса Entity SQL кэшируются, последующее выполнение того же запроса занимает еще меньше времени. Вы также можете использовать скомпилированные запросы LINQ, чтобы уменьшить эту стоимость в последующих выполнениях.

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

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

РЕДАКТИРОВАТЬ в ответ на ваш комментарий и редактировать.

Мне кажется, что у вас сложилось впечатление, что компиляция EF-запроса каким-то образом изменит сгенерированный SQL-код, который будет выполняться в базе данных (вы упоминаете, что скомпилированные запросы приводят к параметризованным SQL-запросам?). Это не относится к делу. Независимо от того, выполняете ли вы запрос напрямую или используете compiledQuery.Invoke, тот же код SQL будет запущен против БД. Более того, вы не имеете полного контроля над ним, вы скорее полагаетесь на ORM, чтобы сгенерировать его наилучшим образом. В некоторых случаях это не оптимально, и именно здесь приходят SP.

Итак, подведем итог:

  • Компиляция запросов - это просто оптимизация на стороне приложения. Это экономит время на компиляцию запроса, который снова используется в коде.
  • Хранимые процедуры могут использоваться для настройки вашего кода SQL и обеспечения его максимально точного соответствия вашей цели, что дает возможность добиться максимальной производительности на уровне базы данных.

Ни в коем случае одна техника не может заменить другую.

Несколько консервированных ответов от известных экспертов: Пол Нильсен Зачем использовать хранимые процедуры?

Адам Мачаник: Нет, хранимые процедуры НЕ плохие

Другие вопросы по тегам