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

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

Многие разработчики и администраторы систем на базе 1С сталкиваются с ситуацией, когда удаление даже небольшого количества объектов (например, 30 000 элементов справочника) затягивается на долгие часы. Рассмотрим подробно, почему стандартные механизмы платформы работают именно так, и разберем способы, которые помогут значительно ускорить этот процесс.

Почему стандартное удаление работает долго?

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

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

  1. Количество таблиц в конфигурации. В современных тяжелых решениях (ERP, КА, УТ 11) количество таблиц может исчисляться тысячами. Платформа обязана проверить каждую, даже если она пуста.
  2. Составные типы данных. Если в базе много реквизитов с типом «Любая ссылка» или составным типом, включающим удаляемый справочник, количество соединений в SQL-запросах возрастает лавинообразно. Это создает колоссальную нагрузку на процессор и дисковую подсистему.
  3. Файловый режим работы. В файловых базах поиск ссылок выполняется последовательно и не может эффективно использовать мощности современных многоядерных процессоров. Вся база данных при этом может быть заблокирована для других операций.
  4. Отсутствие актуальных индексов. Если статистика SQL-сервера устарела или индексы фрагментированы, построение плана запроса для поиска ссылок может занять значительно больше времени.

Способ 1: Непосредственное программное удаление

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

Рассмотрим пример кода для быстрого удаления элементов справочника:


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

Важное предупреждение: Используйте этот метод с осторожностью. Если на удаляемый объект все же есть ссылки в базе, они станут «битыми» (вместо названия объекта в отчетах будет отображаться текст «Объект не найден»).

Способ 2: Оптимизация поиска ссылок через сторонние инструменты

Существуют специализированные инструменты, которые выполняют проверку ссылок гораздо эффективнее стандартной обработки. Разберем, за счет чего достигается ускорение в таких разработках, как «Инструменты разработчика» (ИР) или внешние обработки для массового удаления:

Способ 3: Оптимизация кода проверки иерархии

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

Посмотрим на пример неэффективного кода:


Если СтрокаТаблицы.Номенклатура.ПринадлежитЭлементу(НужнаяГруппа) = Ложь Тогда
    Продолжить;
КонецЕсли;

Этот метод заставляет систему каждый раз обращаться к базе данных, чтобы выстроить всю цепочку родителей для конкретного элемента. Выясним, как это ускорить. Один из вариантов — предварительно кэшировать родителя в таблицу значений и проверять его напрямую, либо использовать запросы.

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


// Предварительно получаем родителя и проверяем его
Если СтрокаТаблицы.ГруппаНоменклатуры = НужнаяГруппа Тогда
    // Действие
КонецЕсли;

Если же необходимо проверить вхождение в группу на любом уровне вложенности, наиболее правильным решением будет использование запроса с условием В ИЕРАРХИИ. Платформа оптимизирует такие запросы на уровне SQL, что работает в десятки раз быстрее метода ПринадлежитЭлементу() в цикле.


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Номенклатура.Ссылка
    |ИЗ
    |   Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |   Номенклатура.Ссылка В ИЕРАРХИИ(&Группа)";

Запрос.УстановитьПараметр("Группа", НужнаяГруппа);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
// Далее работаем с готовым массивом/таблицей подходящих ссылок

Рекомендации по ускорению массовых операций

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

  1. Отключение полнотекстового поиска. Перед массовым удалением рекомендуется приостановить регламентные задания полнотекстового поиска, так как обновление индекса при каждом удалении сильно замедляет процесс.
  2. Режим монопольного доступа. Если возможно, выполняйте удаление в монопольном режиме. Это позволит SQL-серверу более эффективно управлять блокировками таблиц.
  3. Обслуживание базы данных. Перед масштабными операциями очистки выполните обновление статистики и дефрагментацию индексов через консоль управления СУБД.
  4. Увеличение частоты транзакций. Если вы пишете свою обработку удаления, не помещайте удаление всех 30 000 объектов в одну транзакцию. Фиксируйте транзакцию каждые 500–1000 объектов, чтобы избежать чрезмерного роста лога транзакций (LDF).

Таким образом, мы выяснили, что медленное удаление — это не баг, а следствие строгого контроля целостности данных. Выбирая между безопасностью (стандартное удаление) и скоростью (программное удаление), всегда оценивайте риски появления битых ссылок в вашей информационной системе.

← На главную