Следует ли использовать master.dbo при доступе к процедурам sp_? - PullRequest
1 голос
/ 26 июня 2019

Я на 100% убежден, что это дубликат, но после более чем часа поиска я просто не могу найти ответ.

При использовании специальных процедур (т. Е. sp_, таких как sp_executesql), разумно ли использовать полный трехкомпонентный идентификатор master.dbo (или master..) или просто использовать их как есть? Я ищу наиболее оптимизированную версию этого:

1. sp_executesql
2. master..sp_executesql
3. master.dbo.sp_executesql

Являются ли 2 и 3 идентичными с точки зрения производительности, особенно в отношении вышеизложенного (т. Е. Ссылаясь на master), и безопасно ли это для пользователя master.. или вы не должны рисковать даже на master, поскольку кто-то еще может создать другую схему там в какой-то момент?

Очень ценится.

1 Ответ

3 голосов
/ 27 июня 2019

TL; DR;
Не должно быть заметной разницы в производительности.

Длинная история:
Всякий раз, когда вы выполняете хранимую процедуру, которая начинается с префикса sp_, SQL Server сначала будет искать ее в master.dbo, поэтому все три параметра должны иметь одинаковую производительность.

Из статьи, опубликованной Эриком Коббом в 2015 году и озаглавленной Почему бы вам не ставить префикс ваших хранимых процедур с «sp _»

Всякий раз, когда SQL Server видит «sp_» в начале хранимой процедуры, он сначала пытается найти процедуру в базе данных master. Как указано в документации Microsoft выше, «этот префикс используется SQL Server для обозначения системных процедур», поэтому, когда SQL Server видит «sp_», он начинает поиск системных процедур. Только после того, как он выполнил поиск по всем процедурам в базе данных master и определил, что вашей процедуры нет, он вернется в вашу базу данных, чтобы попытаться найти хранимую процедуру.

Кроме того, он цитирует другую официальную документацию (со ссылкой на версию 2008, работающую над поиском текущей версии):

Определяемая пользователем хранимая процедура, имя которой совпадает с именем системной хранимой процедуры и является неквалифицированным или находится в схеме dbo, никогда не будет выполняться; вместо этого всегда будет выполняться системная хранимая процедура.

Эту цитату, хотя я не смог найти в документации текущей версии, я легко могу доказать.
Рассмотрим следующий скрипт:

USE <YourDatabaseNameHere> -- change to the actual name of the db, of course
GO

CREATE PROCEDURE dbo.sp_who
AS
    SELECT 'Zohar peled' as myName
GO

-- change to the actual name of the db, of course
EXEC <YourDatabaseNameHere>.dbo.sp_who
EXEC dbo.sp_who
EXEC sp_who

GO

DROP PROCEDURE  dbo.sp_who  -- cleanup

При тестировании в версии 2016 года (это сервер, который у меня был доступен для тестирования), Все три оператора exec выполняли системную процедуру. Я не мог найти способ выполнить мою процедуру.

Теперь я не могу возиться с master DB на моем сервере, поэтому я могу только показать, что это верно для существующих системных процедур, но я уверен, что это будет то же самое для любой процедуры, которая начинается с префикса sp_, даже если вы сами записали ее в основную базу данных и в свою собственную, как Аарон Бертран проиллюстрировал на своей статье под заголовком Другая сторона эффект: двусмысленность

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

Как упоминалось в предыдущем пункте, процедуры с именем «sp_» будут выполняться медленнее. Это может быть не всегда заметно, но оно есть. Подключение к базе данных DatabaseA, переход к базе данных master и сканирование каждой хранимой там процедуры, затем возврат к базе данных DatabaseA и выполнение процедуры всегда будут занимать больше времени, чем просто подключение к базе данных DatabaseA и ее выполнение.

Обратите внимание, что в этом параграфе говорится о проблемах производительности, связанных с выполнением пользовательской хранимой процедуры с префиксом sp_, поэтому давайте на минуту остановим этот процесс:

Предположим, что SQL Server должен будет сканировать все хранимые процедуры в текущей схеме, и только затем, если не найден, перейдите к Master.Dbo и начните искать там.
Легко увидеть, чем больше процедур у вас в схеме, тем дольше это занимает. Однако - вы когда-нибудь замечали, сколько времени требуется SQL Server, чтобы найти процедуру, необходимую для запуска? Я работаю с SQL Server, начиная с версии 2000, и у меня была общая база данных, содержащая сотни процедур, и все они были ограничены одной и той же схемой, но это никогда не было проблемой производительности.
Фактически, за более чем 15-летний опыт работы с SQL Server я никогда не сталкивался с проблемой производительности, вызванной временем, которое требуется SQL Server для поиска хранимой процедуры, которая ему требуется для запуска.

...