Кто-нибудь может объяснить, почему удаление и воссоздание хранимых процедур в SQL Server 2005 вызывает гораздо большее начальное замедление, чем ожидалось? - PullRequest
6 голосов
/ 12 августа 2010

Мой первый пост здесь, пожалуйста, будьте нежны. =) * * Тысяча одна

Я работаю в компании, унаследовавшей обслуживание системы на заказ, используемой одним из наших клиентов. Предыдущий разработчик (больше не с нами) зашифровал все объекты базы данных (WITH ENCRYPTION).

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

База данных находится на SQL Express 2005 в производстве. Мы хотим запустить на нем профилировщик, но поскольку различные объекты зашифрованы, большинство вызовов хранимых процедур и т. Д. Отображаются как «- зашифрованный текст».

Не очень полезно. Я написал небольшое консольное приложение на C # для расшифровки всех объектов базы данных, которое, насколько я могу судить, прекрасно работает

Он находит все зашифрованные объекты в базе данных и для каждого из них дешифрует его, удаляет предложение with encryption, удаляет оригинал и воссоздает его, используя новый текст «без шифрования».

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

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

У меня также возникает та же проблема, если я удаляю и воссоздаю объекты базы данных, используя их оригинальные сценарии (с сохранением предложения WITH ENCRYPTION).

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

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

Я сделал несколько случайных ударов в темноте, перестраивая индексы и обновляя статистику - это никак не повлияло.

Мы могли бы написать что-нибудь для выполнения всех 540 функций, триггеров, спроков и т. Д., Чтобы предотвратить первый реальный вызов от пользователя, однако после перезапуска SQL-сервера (и наш клиент время от времени перезапускает их сервер) планы выполнения будут отброшены, и нам потребуется снова запустить тот же инструмент. Для меня это не представляется приемлемым вариантом (также не увеличивает свойство CommandTimeout), я хочу знать, почему я вижу такое поведение.

Я использовал sys.dm_exec_query_plan и sys.dm_exec_sql_text, чтобы посмотреть планы выполнения, и использовал DBCC DROPCLEANBUFFERS и DBCC FREEPROCCACHE как часть моего тестирования.

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

Заранее спасибо,

Энди.

- EDIT -

Я не совсем знаю, как я это пропустил, но монитор активности показывает, что сеанс блокируется перекомпиляцией табличной функции. Компиляция занимает слишком много времени, и заблокированный запрос достигает тайм-аута.

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

Я попытался обрезать журнал, который не дал никакого эффекта. Мне все еще нужно взглянуть на размеры файлов.

- Другое редактирование -

TVF возвращает временную таблицу и имеет 12 внешних объединений в запросе, все на sys.server_principals или sys.database_role_members.

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

Ответы [ 3 ]

9 голосов
/ 12 августа 2010

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

Exec sp_msForEachTable @COMMAND1= 'DBCC DBREINDEX ( "?")'

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

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

Четвертая рекомендация: убедитесь, что на вашем сервере достаточно памяти.Убедитесь, что ваши файлы журнала транзакций и файлы данных не растут автоматически после всех этих больших обновлений индексов и объектов.Это может произойти НАВСЕГДА, особенно на оборудовании с низкой спецификацией, например, у вас может работать SQL Express.

Пятая рекомендация: Запустите трассировку SQL Server Profiler для базы данных и посмотрите, какие операторы запускаются конкретно,и которые истекают.«Увеличить» на тех и анализировать их по частям и посмотреть, что случилось.Это, вероятно, просто потребует много хорошей старой тяжелой работы, чтобы полностью понять.

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

3 голосов
/ 12 августа 2010

Еще один выстрел в темноте: были ли вычисленные столбцы, которые вы должны были отбросить, изначально сохраняться (а не сохраняться после воссоздания) или наоборот?

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

1 голос
/ 19 августа 2010

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

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

Я всвяжитесь с Microsoft по этому вопросу (впервые я использовал свое право на поддержку MSDN), поэтому мы надеемся, что мы узнаем больше, и я опубликую то, что обнаружил.

Спасибо всем за помощь,мы добираемся туда!

...