Эффективность хранимых процедур по сравнению с необработанными запросами

23

Я много читал по обе стороны этой дискуссии: есть ли существенный выигрыш в производительности, если использовать только хранимые процедуры над необработанными запросами? Я особенно заинтересован в SQL Server, но был бы заинтересован в любых базах данных.

stimms
источник
2
Можете ли вы опубликовать ссылки на некоторые из того, что вы прочитали? Я не думаю, что здесь речь идет о производительности (по крайней мере, не напрямую)
Джек Дуглас
1
@JackDouglas, зацени ответ Мрденни. Производительность во многом является частью этого вопроса / ответа.
Томас Стрингер

Ответы:

31

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

И не забывайте о проблемах безопасности (динамический SQL, минимальные разрешения и т. Д.), Которые исчезают при использовании хранимых процедур.

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

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

Учитывая, что SQL-инъекция является самым простым способом проникновения в базу данных, это очень важно.

mrdenny
источник
@mrdenny - можете ли вы получить тот же эффект с «необработанными запросами», если они параметризованы?
Джек Дуглас
Да, если они полностью параметризованы. Однако это не решает проблемы безопасности, которые решаются с помощью хранимых процедур.
Мрденни
10

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

В худшем случае в последнее время выделяется 8 ГБ для экземпляра, кэш планов 3 ГБ, планы одноразового использования 2,5 ГБ. Большинство из них были SQL2005, поэтому не было возможности попробовать оптимизировать для специальных рабочих нагрузок.

Конечно, становится все труднее включать производительность в обоснование процедур над необработанными запросами. Один из самых сильных аргументов для меня сейчас: «Если вы используете процедуры, мне гораздо легче помочь при возникновении проблем с производительностью». Динамический интерфейс / linq / orm не препятствует настройке, но может серьезно ограничить ваши возможности.

Марк Стори-Смит
источник
Здесь есть отличная статья, в том числе сценарии удаления этих одноразовых планов. sqlskills.com/blogs/kimberly/…
SomeGuy
7

SQL Server кеширует и оптимизирует хранимые процедуры и специальный SQL таким же образом. Например, эта процедура:

create procedure dbo.TestSB(@id int) as select * from Orders where id = @id

Будет оптимизирован и кэширован идентично:

select * from Orders where id = @id

Тем не менее, следующий специальный SQL не может быть эффективно кэширован из-за жестко заданного значения:

select * from Orders where id = 42

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

Andomar
источник
+1 особенно если вы заставляете весь доступ проходить через своих SP, и они хорошо продуманы как транзакционный API, а не просто слой CRUD
Джек Дуглас
В 2008+ id = 42запрос можно оптимизировать, используя тот же план в зависимости от настроек простой / принудительной параметризации. Конечно, запросы должны быть правильно параметризованы. :-)
Аарон Бертран