Мой первый пост здесь, пожалуйста, будьте нежны. =) * * Тысяча одна
Я работаю в компании, унаследовавшей обслуживание системы на заказ, используемой одним из наших клиентов. Предыдущий разработчик (больше не с нами) зашифровал все объекты базы данных (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.
Кажется, я помню, что читал что-то о перекомпиляции и временных таблицах, и мне придется еще раз проверить ..