Производительность SQL-сервера: что быстрее, хранимая процедура или представление? - PullRequest
35 голосов
/ 22 октября 2009

Что быстрее в SQL Server 2005/2008, хранимой процедуре или представлении?

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

Ответы [ 9 ]

69 голосов
/ 22 октября 2009

Хранимые процедуры (SP) и представления SQL - это разные "звери", как уже несколько раз говорилось в этом посте.

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

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

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

12 голосов
/ 22 октября 2009

К сожалению, это не тот тип зверя.

Хранимая процедура представляет собой набор операторов T-SQL и МОЖЕТ возвращать данные. Он может выполнять все виды логики и не обязательно возвращать данные в наборе результатов.

Представление - это представление данных. В основном он используется как абстракция одной или нескольких таблиц с базовыми объединениями. Это всегда набор результатов, состоящий из нуля, одной или нескольких строк.

Я подозреваю, что ваш вопрос больше похож на:

Что быстрее: SELECT в представлении или эквивалентном операторе SELECT в хранимой процедуре, если для тех же базовых таблиц выполняются объединения с одинаковыми предложениями where?

8 голосов
/ 22 октября 2009

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

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

Представление по сути является сохраненным оператором SQL.

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

Ссылка на эти ссылки документацию, подтверждающую мой ответ.

http://www.sql -server-performance.com / советы / stored_procedures_p1.aspx

http://msdn.microsoft.com/en-us/library/ms998577.aspx

Кроме того, если вы ищете все способы оптимизации производительности на SQL Server, вторая ссылка выше - хорошее место для начала.

5 голосов
/ 22 октября 2009

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

4 голосов
/ 23 января 2014

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

Но вы не можете использовать результаты хранимой процедуры в запросах select или join.

Если вы не хотите использовать набор результатов в другом запросе, лучше использовать SP.

А остальные детали и различия упоминаются людьми на этом форуме и в других местах.

3 голосов
/ 25 октября 2009

Хранимые процедуры и представления различны и имеют разные цели. Я смотрю на представления как на постоянные запросы. Я смотрю на хранимые процедуры как на модули кода.

Например, допустим, у вас есть таблица с именем tblEmployees, в которую входят следующие два столбца: DateOfBirth и MaleFemale.

Представление под названием viewEmployeesMale, которое отфильтровывает только сотрудников мужского пола, может быть очень полезным. Представление под названием viewEmployeesFemale также очень полезно. Оба эти взгляда самоописательны и интуитивно понятны.

Теперь, допустим, вам нужно составить список всех сотрудников мужского пола в возрасте от 25 до 30 лет. Я бы хотел создать хранимую процедуру для получения этого результата. Хотя это, безусловно, может быть построено как представление, на мой взгляд, хранимая процедура лучше подходит для решения этой проблемы. Манипулирование датами, особенно когда нули являются фактором, может стать очень сложным.

3 голосов
/ 23 октября 2009

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

Полагаю, что я говорю вместо sp vs views, думаю sp and views:)

0 голосов
/ 08 ноября 2017

Я знаю, что не должен превращать это в «дискуссию», но я очень заинтересован в этом и просто подумал, что поделюсь своими эмпирическими наблюдениями за конкретной ситуацией, с особой ссылкой на все комментарии выше в котором указывается, что эквивалентный оператор SELECT, выполняемый из хранимой процедуры и представления, должен в целом иметь одинаковую производительность.

У меня есть представление в базе данных "A", которое объединяет 5 таблиц в отдельную базу данных (db "B"). Если я присоединяюсь к базе данных «A» в SSMS и SELECT * из представления, это возвращает> 3 минуты, чтобы вернуть 250000 строк. Если я возьму оператор выбора со страницы дизайна представления и выполню его непосредственно в SSMS, это займет <25 секунд. Помещение того же оператора select в хранимую процедуру дает ту же производительность, когда я выполняю эту процедуру. </p>

Не делая каких-либо наблюдений за абсолютной производительностью (db "B" является базой данных AX, к которой мы не имеем права прикасаться!), Я все еще абсолютно уверен, что в этом случае использование SP на порядок быстрее, чем использование представление для извлечения тех же данных, и это применимо ко многим другим подобным представлениям в данном конкретном случае.

Я не думаю, это как-то связано с созданием соединения с другим БД, если только с помощью представления он каким-то образом никогда не сможет кэшировать соединение, тогда как выбор делает, потому что я могу переключаться 2 выбирает в одном и том же окне SSMS несколько раз, и производительность каждого запроса остается неизменной. Кроме того, если я подключаюсь напрямую к базе данных db "B" и запускаю команду select без ссылки dbname.dbo ...., это занимает то же время.

Есть мысли у кого-нибудь?

0 голосов
/ 03 марта 2016

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

  • SP будет поддерживать порядок набора результатов; то есть, включая оператор ORDER BY. Вы не можете сделать это в представлении.
  • SP полностью скомпилирован и требует только exec для его вызова. Представление все еще требует SELECT * FROM view, чтобы вызвать его; то есть выборка в скомпилированном выборе в представлении.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...