Почему так медленно удаляются помеченные документы в 1С и как ускорить этот процесс?

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

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

Основные причины замедления процесса удаления

Для понимания проблемы проанализируем ситуацию: почему даже не проведенные документы, не имеющие движений по регистрам, удаляются долго? В платформе 1С и СУБД при удалении каждого объекта происходит множество скрытых процессов:

  1. Транзакции большого объема. При удалении всех объектов в единой транзакции платформа и СУБД тратят огромное количество ресурсов на блокировки и последующую фиксацию (commit) транзакции. Чем больше объектов обрабатывается за один раз, тем длительнее задержки.
  2. Запись в журнал регистрации. По умолчанию каждый факт удаления объекта фиксируется в журнале регистрации. При массовом удалении запись миллионов событий создает колоссальную нагрузку на дисковую подсистему.
  3. Служебная логика и подписки на события. При вызове метода Удалить() платформой генерируются события ПередУдалением и ПриУдалении, вызывающие подписки на события. В них может быть зашита тяжелая прикладная логика.
  4. Регистрация изменений для планов обмена. Если удаляемые объекты входят в состав хотя бы одного плана обмена с включенной авторегистрацией, на каждый документ создаются записи в таблицах регистрации изменений для всех узлов.
  5. Каскадное удаление табличных частей. Документы с большим количеством строк в табличных частях требуют удаления множества записей из подчиненных таблиц СУБД, что генерирует записи в журнале транзакций СУБД.
  6. Индексация полнотекстового поиска (ППД). Платформа регистрирует изменения для служебных таблиц полнотекстового поиска, отвлекая ресурсы сервера.

Способ 1. Порционное (выборочное) удаление объектов

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

Рассмотрим пример кода для обработки массива ссылок порциями:


МассивДляУдаления = Новый Массив;
Счетчик = 0;

Для Каждого СсылкаИзСписка Из МассивПомеченныхДокументов Цикл
    МассивДляУдаления.Добавить(СсылкаИзСписка);
    Счетчик = Счетчик + 1;
    
    Если Счетчик >= 1000 Тогда
        УдалитьПакетДокументов(МассивДляУдаления);
        МассивДляУдаления.Очистить();
        Счетчик = 0;
    КонецЕсли;
КонецЦикла;

Если МассивДляУдаления.Количество() > 0 Тогда
    УдалитьПакетДокументов(МассивДляУдаления);
КонецЕсли;

Способ 2. Использование свойства ОбменДанными.Загрузка

Чтобы отключить выполнение избыточных проверок, бизнес-логики в модулях объектов и вызова подписок на события, перед удалением необходимо устанавливать свойство ОбменДанными.Загрузка = Истина.

Посмотрим на пример удаления отдельного объекта с использованием данного флага:


Для Каждого СсылкаДокумента Из МассивПроверенныхСсылок Цикл
    Попытка
        ОбъектДокумент = СсылкаДокумента.ПолучитьОбъект();
        Если ОбъектДокумент <> Неопределено Тогда
            ОбъектДокумент.ОбменДанными.Загрузка = Истина;
            ОбъектДокумент.Удалить();
        КонецЕсли;
    Исключение
        ЗаписатьВЛог("Не удалось удалить объект: " + ОписаниеОшибки());
    КонецПопытки;
КонецЦикла;

Способ 3. Отключение журнала регистрации и фоновых заданий

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

Также перед стартом операции необходимо полностью заблокировать выполнение регламентных и фоновых заданий (включая индекс полнотекстового поиска) в консоли администрирования кластера 1С.

Способ 4. Оптимизация на уровне СУБД (MS SQL Server)

При удалении миллионов строк журнал транзакций СУБД (файл LDF) быстро разрастается, а регулярные операции авторасширения тормозят процесс. Для предотвращения задержек выстроим правильный порядок действий на сервере баз данных:

  1. Перевести модель восстановления базы данных (Recovery Model) из режима Full в режим Simple на период проведения чистки.
  2. Увеличить размер файла журнала транзакций заранее, чтобы избежать его постоянного авторасширения во время операций DELETE.
  3. После завершения удаления выполнить обслуживание индексов и пересчет статистики СУБД.

Способ 5. Оптимизация контроля ссылок через НайтиПоСсылкам

Штатный механизм поиска ссылок выполняет поиск по всем таблицам базы данных. Чтобы ускорить этот этап, разработаем алгоритм проверки ссылочной целостности с помощью метода НайтиПоСсылкам():


МассивСсылок = Новый Массив;
// Заполняем МассивСсылок помеченными на удаление документами

ТаблицаСсылок = НайтиПоСсылкам(МассивСсылок);

// В ТаблицеСсылок содержатся объекты, ссылающиеся на наши документы.
// Отфильтровываем объекты, на которые нет внешних ссылок, 
// и отправляем их на удаление.

Проанализировав комплекс мер, можно сделать вывод: комбинирование порционной обработки, включения режима ОбменДанными.Загрузка = Истина, временного отключения журнала регистрации и оптимизации настроек СУБД позволяет сократить время удаления помеченных объектов с десятков часов до 1–2 часов.

← На главную