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