Хотя я уважаю заявителя, я смиренно не согласен с предоставленным ответом, а не по «религиозным причинам». Другими словами, я считаю, что Microsoft не предоставила средства, которое уменьшило бы потребность в руководстве по использованию хранимых процедур.
Любое руководство, предоставленное разработчику, которое поддерживает использование необработанных текстовых SQL-запросов, должно быть заполнено множеством предостережений, так что я думаю, что самый разумный совет - сильно поощрять использование хранимых процедур и отговаривать группы разработчиков от участия в практике. встраивания операторов SQL в код или отправки необработанных простых текстовых SQL-запросов вне SQL SPROC (хранимых процедур).
Я думаю, что простой ответ на вопрос о том, почему использовать SPROC, заключается в том, что создатель предположил: SPROC анализируются, оптимизируются и компилируются. Таким образом, их планы запросов / выполнения кэшируются, потому что вы сохранили статическое представление запроса, и вы, как правило, будете изменять его только по параметрам, что неверно в случае скопированных / вставленных операторов SQL, которые, вероятно, изменяются от страницы к странице и компоненту / уровню, и часто меняются в зависимости от того, какие разные таблицы, даже имена баз данных, могут быть указаны при вызове. Разрешение для этого типа динамического ad hocОтправка SQL значительно снижает вероятность того, что DB Engine повторно использует план запросов для ваших специальных операторов в соответствии с некоторыми очень строгими правилами. Здесь я делаю различие между динамическими специальными запросами (в духе поставленного вопроса) и использованием эффективной системы SPROC sp_executesql.
Более конкретно, существуют следующие компоненты:
- Планы последовательных и параллельных запросов, которые не содержат пользовательский контекст и допускают повторное использование ядром БД.
- Контекст выполнения, который позволяет повторно использовать план запроса новым пользователем с другими параметрами данных.
- Кэш процедур, который запрашивает механизм БД для повышения эффективности, к которой мы стремимся.
Когда с веб-страницы выдается оператор SQL, называемый «оператор ad hoc», механизм ищет существующий план выполнения для обработки запроса. Поскольку это текст, отправленный пользователем, он будет принят, проанализирован, скомпилирован и выполнен, если он действителен. В это время он получит нулевую стоимость запроса. Стоимость запроса используется, когда механизм БД использует свой алгоритм, чтобы определить, какие планы выполнения следует исключить из кэша.
По умолчанию специальные запросы получают исходную стоимость запроса равную нулю. При последующем выполнении точно такого же специального текста запроса другим пользовательским процессом (или тем же самым) текущая стоимость запроса сбрасывается до первоначальной стоимости компиляции. Поскольку стоимость компиляции нашего специального запроса равна нулю, это не сулит ничего хорошего для возможности повторного использования. Очевидно, что ноль - это наименее значное целое число, но зачем его выселять?
Когда возникают проблемы с памятью, и они будут возникать, если у вас есть часто используемый сайт, механизм БД использует алгоритм очистки, чтобы определить, как он может восстановить память, которую использует кэш процедур. Он использует текущую стоимость запроса, чтобы решить, какие планы выселить. Как вы можете догадаться, планы с нулевой стоимостью являются первыми, которые будут выселены из кэша, потому что ноль, по сути, означает «нет текущих пользователей или ссылок на этот план».
- Примечание. Специальные планы выполнения - текущая стоимость увеличивается для каждого пользовательского процесса по сравнению с первоначальной стоимостью компиляции плана. Однако максимальная стоимость плана не может быть больше его первоначальной стоимости компиляции ... в случае специальных запросов ... ноль. Таким образом, он будет «увеличен» на это значение ... ноль - что по сути означает, что он останется самым дешевым планом.
Поэтому вполне вероятно, что такой план будет выселен первым, когда возникнет давление памяти.
Таким образом, если у вас есть серверная сборка с большим объемом памяти «вне ваших потребностей», вы можете столкнуться с этой проблемой не так часто, как с загруженным сервером, который имеет только «достаточную» память для обработки своей рабочей нагрузки. (Извините, объем памяти сервера и его использование несколько субъективны / относительны, хотя алгоритм не так.)
Теперь, если я на самом деле ошибаюсь по поводу одного или нескольких пунктов, я, безусловно, открыт для исправления.
Наконец, автор написал:
«Теперь у нас есть оптимизация на уровне операторов, поэтому правильно параметризованный запрос, поступающий из приложения, может использовать тот же план выполнения, что и этот запрос, встроенный в хранимую процедуру».
Я полагаю, что автор ссылается на опцию «оптимизировать для специальных рабочих нагрузок».
Если это так, эта опция позволяет выполнить двухэтапный процесс, который позволяет избежать немедленной отправки полного плана запроса в кэш процедур. Он отправляет туда только заглушку меньшего размера. Если точный вызов запроса отправляется обратно на сервер, в то время как заглушка запроса все еще находится в кэше процедур, полный план выполнения запросов в это время сохраняется в кэше процедур. Это экономит память, что во время инцидентов с памятью может позволить алгоритму вытеснения выселять вашу заглушку реже, чем больший план запроса, который был кэширован. Опять же, это зависит от вашей памяти сервера и использования.
Однако вы должны включить эту опцию, так как по умолчанию она отключена.
Наконец, я хочу подчеркнуть, что зачастую разработчики встраивают SQL в страницы, компоненты и другие места по той причине, что они хотят быть гибкими и отправлять динамический запрос SQL в ядро базы данных. Следовательно, в реальном случае использования отправка того же текста call-over-call вряд ли произойдет, как и эффективность кэширования, которую мы ищем при отправке специальных запросов на SQL Server.
Для получения дополнительной информации, пожалуйста, смотрите:
https://technet.microsoft.com/en-us/library/ms181055(v=sql.105).aspx
http://sqlmag.com/database-performance-tuning/don-t-fear-dynamic-sql
Бест,
Генри