Почему дефрагментация индексов SQL Server выполняется аномально долго и как это исправить?

Системный администратор 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При администрировании высоконагруженных баз данных 1С системные администраторы нередко сталкиваются с ситуацией, когда регламентная дефрагментация (реорганизация) индексов начинает выполняться в разы дольше обычного — вместо 2–3 часов процесс растягивается на 12 и более часов, перекрывая рабочее время и вызывая блокировки при работе пользователей с документами (например, Требование-накладная). При этом полное перестроение (реиндексация) тех же баз завершается штатно за короткий промежуток времени. Разберем детально, почему возникает эта проблема и как правильно выстроить регламентное обслуживание MS SQL Server.

Причины медленной работы операции дефрагментации (REORGANIZE)

Проанализируем техническую разницу между операциями REORGANIZE (дефрагментация) и REBUILD (перестроение индексов), которая напрямую влияет на длительность регламентных процедур:

  1. Строгая однопоточность дефрагментации: операция ALTER INDEX ... REORGANIZE в MS SQL Server выполняется исключительно в один поток (MAXDOP = 1). Она не способна задействовать несколько процессорных ядер. В то же время перестроение индексов ALTER INDEX ... REBUILD использует параллелизм, за счет чего на мощных многоядерных серверах отрабатывает значительно быстрее, даже выполняя больший физический объем работы.
  2. Сжатие LOB-данных (полей неограниченной длины): при реорганизации индексов СУБД выполняет принудительное уплотнение страниц с данными типа LOB (в терминах 1С это поля ХранилищеЗначений, присоединенные файлы, длинные строки). Если в базе накопился большой объем файлов или истории версионирования, однопоточная реорганизация таких таблиц создает предельную нагрузку на дисковую систему и процессор.
  3. Фрагментация журнала транзакций (большое количество VLF): операция REORGANIZE протоколирует перемещение каждой страницы по отдельности. Если файл журнала транзакций (.ldf) разбит на сотни или тысячи мелких виртуальных лог-файлов (Virtual Log Files — VLF), скорость записи многократно снижается из-за накладных расходов на их переключение.
  4. Обработка фантомных записей (Ghost Records): при интенсивном удалении данных в 1С дефрагментация тратит время на очистку неудаленных страниц и фантомных записей, что кратно увеличивает время работы задания.
  5. Отсутствие автоматического обновления статистики: в отличие от перестроения, операция REORGANIZE не обновляет статистику распределения данных. Устаревшая статистика заставляет оптимизатор строить неоптимальные планы запросов (например, полное сканирование таблицы вместо поиска по индексу), что приводит к длительным транзакциям и конфликтам блокировок при открытии и проведении документов в 1С.

Шаг 1. Диагностика узких мест и состояния СУБД

Рассмотрим, какие метрики необходимо проверить в первую очередь при возникновении зависаний регламентных заданий:

  1. Проверка количества VLF в журнале транзакций: выясним, не фрагментирован ли лог транзакций. Для этого выполним диагностический запрос:
    
    USE [upp];
    GO
    DBCC LOGINFO;
    GO
    

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

  2. Анализ текущих ожиданий (Wait Types): во время зависания дефрагментации посмотрим, в какие ресурсы упирается процесс через системные представления sys.dm_os_waiting_tasks и sys.dm_exec_requests. Ожидания PAGEIOLATCH_* указывают на деградацию дисковой подсистемы, WRITELOG — на задержки записи в файл транзакций, а LCK_* — на блокировки другими процессами.

Шаг 2. Устранение фрагментации журнала транзакций

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

  1. Выполним резервное копирование журнала транзакций (при полной модели восстановления) или временно переключим базу в простой режим для сброса лога:
    
    USE [upp];
    GO
    ALTER DATABASE [upp] SET RECOVERY SIMPLE;
    GO
    DBCC SHRINKFILE ([upp_log], 1024);
    GO
    ALTER DATABASE [upp] SET RECOVERY FULL;
    GO
    
  2. Установим корректный начальный размер файла журнала транзакций (соответствующий суточному объему изменений) и зададим фиксированный авторост крупными блоками (например, 1024 МБ или 2048 МБ вместо процентов), чтобы предотвратить повторное появление тысяч мелких VLF.

Шаг 3. Оптимизация регламентов обслуживания индексов

Типовые планы обслуживания (Maintenance Plans) часто запускают дефрагментацию всех индексов подряд, что неэффективно для больших баз 1С. Настроим адаптивное обслуживание на основе следующих правил:

  1. Исключение маленьких таблиц: не обслуживаем индексы размером менее 1000–1500 страниц (менее ~8–12 МБ). Для небольших таблиц фрагментация не влияет на производительность, а их обработка впустую тратит время регламентного окна.
  2. Дифференцированный подход по уровню фрагментации:
    • Если фрагментация индекса составляет от 10% до 30% — выполняем ALTER INDEX ... REORGANIZE;
    • Если фрагментация превышает 30% — выполняем ALTER INDEX ... REBUILD.
  3. Использование онлайн-перестроения: в редакциях SQL Server с поддержкой Enterprise перестроение индексов рекомендуется выполнять с параметром ONLINE = ON. Это позволяет не блокировать таблицы для пользователей и параллельно работающих регламентных заданий 1С: ALTER INDEX [ИмяИндекса] ON [dbo].[ИмяТаблицы] REBUILD WITH (ONLINE = ON);
  4. Обязательное отдельное обновление статистики: если ночью выполняется только REORGANIZE, обязательно добавляем отдельным шагом обновление статистики по измененным таблицам: UPDATE STATISTICS [dbo].[ИмяТаблицы] WITH FULLSCAN;

Итоги

Зависание дефрагментации чаще всего обусловлено однопоточностью операции REORGANIZE, наличием LOB-полей и высокой фрагментацией лога транзакций. Отказ от сплошной дефрагментации в пользу порогового обслуживания, устранение фрагментации VLF и принудительное обновление статистики позволяют сократить время регламентных работ и полностью устранить ошибки блокировок в 1С.

← На главную