Интригующая проблема настройки производительности SQL Server - PullRequest
3 голосов
/ 23 октября 2009

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

У нас есть ночной процесс, который запускается и запускается хранимой процедурой, которая вызывает много-много других хранимых процедур. Множество вызываемых хранимых процедур вызывают другие и т. Д. Я рассмотрел некоторые из вызываемых процедур, и в них есть всякие пугающие сложные вещи, такие как обработка строк XML, ненужное чрезмерное использование курсоров, чрезмерное использование подсказок NOLOCK, редкое использование обработки на основе множеств и т. д. - список можно продолжать, это ужасно.

Этот ночной процесс в нашей производственной среде занимает в среднем 1:15. Иногда для запуска требуется 2 часа, что недопустимо. Я создал тестовую среду на оборудовании, идентичном производственному, и запустил процесс. Это заняло 45 минут, когда я впервые запустил его. Если я восстанавливаю базу данных в ту же точку и запускаю ее снова, это займет больше времени: на самом деле, если я повторю это действие несколько раз (восстановление и повторный запуск), процесс будет прогрессивно дольше, пока он не достигнет примерно 2 часов. Это действительно озадачивает меня, потому что я каждый раз восстанавливаю базу данных до одной и той же точки. На сервере нет других пользовательских баз данных.

Я подумал о двух направлениях расследования:

  1. Планы запросов и подмена параметров
  2. Tempdb

В качестве теста я перезапустил SQL Server, чтобы очистить кеш и базу данных tempdb, и повторно запустил процесс с тем же восстановлением базы данных. Процесс занял 45 минут. Я повторил это несколько раз, чтобы убедиться, что это повторяется - снова это заняло 45 минут каждый раз. Затем я предпринял несколько тестов, чтобы попытаться изолировать удивительное увеличение времени выполнения, когда SQL Server не перезапускается:

  1. Запустить начальную хранимую процедуру с RECOMPILE
  2. Перед запуском процедуры выполните executre DBCC FREEPROCCACHE, чтобы очистить кеш процедуры
  3. Перед запуском процедуры выполните CHECKPOINT, а затем DBCC DROPCLEANBUFFERS, чтобы убедиться, что кэш был пустым и чистым
  4. Выполнен следующий скрипт, чтобы гарантировать, что все хранимые процедуры были помечены для перекомпиляции:

    DECLARE @proc_schema SYSNAME
    DECLARE @proc_name SYSNAME
    
    DECLARE prcCsr CURSOR local
        FOR SELECT  specific_schema,
                    specific_name
            FROM    INFORMATION_SCHEMA.routines
            WHERE   routine_type = 'PROCEDURE'
    
    OPEN prcCsr
    
    FETCH NEXT FROM prcCsr INTO @proc_schema, @proc_name
    
    DECLARE @stmt NVARCHAR(MAX)
    WHILE @@FETCH_STATUS = 0
        BEGIN
            SET @stmt = N'exec sp_recompile ''[' + @proc_schema + '].['
                + @proc_name + ']'''
    --        PRINT @stmt   -- DEBUG
            EXEC ( @stmt
                )
    
            FETCH NEXT FROM prcCsr INTO @proc_schema, @proc_name
        END
    

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

Я также исследовал базу данных tempdb и попытался очистить там старые таблицы, как описано в моем другом посте stackoverflow, но я не могу вручную очистить временные таблицы, которые были созданы из переменных таблицы, и похоже, что они хочу исчезнуть самостоятельно (даже после того, как покинул их на 24 часа).

Будем весьма благодарны за любые идеи или предложения по дальнейшему тестированию. Я использую 64-разрядную версию Enterprise Edition SQL Server 2005 с пакетом обновления 3 (SP3) на Windows 2003 R2 Ent. редакция кластера.

С уважением, Mark.

Ответы [ 12 ]

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

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

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

Что делает весь процесс, какова цель выполняемой операции?

Я бы предположил, что выполнение процесса приводит к модификации данных в базе данных. Это тот случай?

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

Если предположить, что происходит изменение данных базы данных, вам также следует изучить:

  • Обновление соответствующей статистики базы данных между каждым запуском процесса.
  • Просмотр уровня индекса фрагментация между каждым процессом запустите и определите, может ли дефрагментация оказаться полезной.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...