Как ускорить удаление большого количества помеченных объектов в 1С после свертки базы

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

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

Анализ причин медленной работы стандартного механизма

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

Проанализируем ситуацию: стандартная обработка сначала собирает все помеченные объекты, а затем начинает проверять каждый из них. Если в списке первыми идут объекты, на которые есть ссылки в "живых" (не помеченных на удаление) документах, система тратит часы на бесполезный поиск ссылок для тех элементов, которые заведомо не могут быть удалены. В итоге время сеанса (например, установленные 12 часов) заканчивается раньше, чем очередь дойдет до реально "свободных" объектов.

Решение 1: Использование специализированного инструментария

Одним из самых эффективных способов решения проблемы является использование сторонних инструментов, таких как "Инструменты разработчика" (автор TormozIT). Рассмотрим, почему этот инструмент работает быстрее:

  1. Кэширование неудаляемых объектов: Программа запоминает объекты, на которые найдены ссылки, и не тратит время на их повторную проверку в текущем цикле.
  2. Групповой поиск ссылок: Вместо одиночных запросов к каждой таблице БД, инструмент выполняет оптимизированные запросы сразу по массиву объектов.
  3. Удаление по типам метаданных: Мы можем выбрать конкретный вид документа или справочника и работать только с ним, что значительно снижает нагрузку на сервер.

Решение 2: Стратегия удаления "Сверху вниз" по метаданным

Вместо того чтобы пытаться удалить всё сразу, разберем методику удаления по типам объектов в определенной последовательности. Это позволяет постепенно разрывать связи между данными. Рекомендуется придерживаться следующего порядка:

Решение 3: Предварительная фильтрация и снятие пометок

Рассмотрим ситуацию, когда в список на удаление попали объекты, которые "и не должны удалиться" (например, документы за последний незакрытый месяц). Система всё равно будет пытаться их проверить. Чтобы ускорить процесс, выполним программное снятие пометки удаления с таких объектов.

Посмотрим на пример простого кода, который поможет снять пометку с документов определенного периода, чтобы они не мешали обработке:


Выборка = Документы.РеализацияТоваровУслуг.Выбрать(НачалоМесяца(ТекущаяДата()), КонецМесяца(ТекущаяДата()));
Пока Выборка.Следующий() Цикл
    Если Выборка.ПометкаУдаления Тогда
        ОбъектДок = Выборка.ПолучитьОбъект();
        ОбъектДок.УстановитьПометкуУдаления(Ложь);
        ОбъектДок.Записать(РежимЗаписиДокумента.Запись);
    КонецЕсли;
КонецЦикла;

После очистки списка от заведомо "неудаляемых" объектов, общее количество элементов в очереди сократится, и стандартная обработка (или Инструменты разработчика) пойдет значительно быстрее.

Решение 4: Программное удаление порциями

Чтобы избежать переполнения лога транзакций SQL и обхода ограничения времени сеанса, проанализируем метод удаления порциями через фоновое задание. Это позволит системе работать в фоновом режиме, не занимая клиентское рабочее место.

Для этого можно использовать метод УдалитьОбъекты(). Выясним, как это реализовать правильно:

  1. Создаем массив объектов (например, 500 штук).
  2. Вызываем УдалитьОбъекты(МассивОбъектов, Истина, НайденныеСсылки).
  3. Параметр Истина включает проверку ссылочной целостности.
  4. Если ссылки найдены, объект пропускается, если нет — удаляется.

Пример реализации порционного удаления:


МассивДляУдаления = Новый Массив;
Выборка = Справочники.Номенклатура.Выбрать(); // Или любой другой запрос по помеченным
Пока Выборка.Следующий() Цикл
    Если Выборка.ПометкаУдаления Тогда
        МассивДляУдаления.Добавить(Выборка.Ссылка);
    КонецЕсли;
    
    Если МассивДляУдаления.Количество() >= 1000 Тогда
        УдалитьОбъекты(МассивДляУдаления, Истина);
        МассивДляУдаления.Очистить();
        // Здесь можно сделать паузу или зафиксировать лог
    КонецЕсли;
КонецЦикла;
// Удаляем остаток
Если МассивДляУдаления.Количество() > 0 Тогда
    УдалитьОбъекты(МассивДляУдаления, Истина);
КонецЕсли;

Проблема памяти и РИБ

В контексте обсуждения упоминается проблема создания образа РИБ (Распределенной информационной базы). Когда в базе висит 200 000 помеченных объектов, они попадают в регистрацию изменений для узлов РИБ. Это вызывает нехватку оперативной памяти при формировании начального образа или первого пакета обмена.

Важный совет: После успешного массового удаления объектов обязательно выполните сжатие (Shrink) базы данных и лога транзакций средствами SQL Server, а также обновите статистики и перестройте индексы. Без этого физический размер файла базы не уменьшится, и проблемы с производительностью при создании образа РИБ могут сохраниться.

Итоги и рекомендации

Подводя итог, можно сказать: если типовая обработка не справляется, не нужно пытаться запустить её снова с теми же параметрами.

Мы рекомендуем:

← На главную