Проведение процедур по свертке информационной базы часто сопровождается подготовкой и массовым удалением сотен тысяч документов. Однако штатная обработка удаления помеченных объектов может работать крайне медленно, растягиваясь на долгие часы или вовсе «зависая». Разберем подробнее причины такой низкой производительности и проанализируем проверенные способы ускорения удаления данных.
Для понимания проблемы проанализируем ситуацию: почему даже не проведенные документы, не имеющие движений по регистрам, удаляются долго? В платформе 1С и СУБД при удалении каждого объекта происходит множество скрытых процессов:
Удалить() платформой генерируются события ПередУдалением и ПриУдалении, вызывающие подписки на события. В них может быть зашита тяжелая прикладная логика.Главная ошибка при удалении большого массива данных — попытка удалить все объекты одним набором. Если разделить массив помеченных документов на небольшие порции (например, по 500–1000 штук) и фиксировать транзакцию для каждой группы отдельно, общее время обработки существенно сократится.
Рассмотрим пример кода для обработки массива ссылок порциями:
МассивДляУдаления = Новый Массив;
Счетчик = 0;
Для Каждого СсылкаИзСписка Из МассивПомеченныхДокументов Цикл
МассивДляУдаления.Добавить(СсылкаИзСписка);
Счетчик = Счетчик + 1;
Если Счетчик >= 1000 Тогда
УдалитьПакетДокументов(МассивДляУдаления);
МассивДляУдаления.Очистить();
Счетчик = 0;
КонецЕсли;
КонецЦикла;
Если МассивДляУдаления.Количество() > 0 Тогда
УдалитьПакетДокументов(МассивДляУдаления);
КонецЕсли;
Чтобы отключить выполнение избыточных проверок, бизнес-логики в модулях объектов и вызова подписок на события, перед удалением необходимо устанавливать свойство ОбменДанными.Загрузка = Истина.
Посмотрим на пример удаления отдельного объекта с использованием данного флага:
Для Каждого СсылкаДокумента Из МассивПроверенныхСсылок Цикл
Попытка
ОбъектДокумент = СсылкаДокумента.ПолучитьОбъект();
Если ОбъектДокумент <> Неопределено Тогда
ОбъектДокумент.ОбменДанными.Загрузка = Истина;
ОбъектДокумент.Удалить();
КонецЕсли;
Исключение
ЗаписатьВЛог("Не удалось удалить объект: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Интенсивная запись событий в журнал регистрации во время удаления тормозит работу системы. На время выполнения свертки и чистки базы рекомендуется отключить регистрацию событий или перевести ее в режим записи только ошибок.
Также перед стартом операции необходимо полностью заблокировать выполнение регламентных и фоновых заданий (включая индекс полнотекстового поиска) в консоли администрирования кластера 1С.
При удалении миллионов строк журнал транзакций СУБД (файл LDF) быстро разрастается, а регулярные операции авторасширения тормозят процесс. Для предотвращения задержек выстроим правильный порядок действий на сервере баз данных:
DELETE.Штатный механизм поиска ссылок выполняет поиск по всем таблицам базы данных. Чтобы ускорить этот этап, разработаем алгоритм проверки ссылочной целостности с помощью метода НайтиПоСсылкам():
МассивСсылок = Новый Массив;
// Заполняем МассивСсылок помеченными на удаление документами
ТаблицаСсылок = НайтиПоСсылкам(МассивСсылок);
// В ТаблицеСсылок содержатся объекты, ссылающиеся на наши документы.
// Отфильтровываем объекты, на которые нет внешних ссылок,
// и отправляем их на удаление.
Проанализировав комплекс мер, можно сделать вывод: комбинирование порционной обработки, включения режима ОбменДанными.Загрузка = Истина, временного отключения журнала регистрации и оптимизации настроек СУБД позволяет сократить время удаления помеченных объектов с десятков часов до 1–2 часов.