Почему долго проводится документ «Установка цен номенклатуры» с большим количеством строк?

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

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

Основные причины медленного проведения документа

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

  1. Передача тяжелых данных с сервера на клиент и структура табличной части. В типовых конфигурациях на управляемых формах табличная часть документа Установка цен номенклатуры часто представлена иерархической структурой типа ДеревоЗначений. При наличии десятков тысяч товаров и нескольких видов цен объем данных в оперативной памяти становится огромным. Возврат управления с сервера на клиент требует длительной сериализации и передачи этой структуры.
  2. Завершение транзакции СУБД и пересчет индексов. До момента окончательной фиксации транзакции (Commit) СУБД производит обновление индексов таблиц регистра сведений и документа. Хотя сторонние сеансы уже могут видеть записанные строки в регистре, основной сеанс ожидает ответа от базы данных о полном завершении транзакции.
  3. Регистрация изменений в планах обмена. Если в системе настроена синхронизация данных (РИБ, обмен с сайтом или внешними системами), платформа 1С автоматически формирует записи регистрации изменений для каждого узла. На объемах в 10 000–90 000 строк это создает колоссальную дополнительную нагрузку.
  4. Выполнение подписок на события и каскадные пересчеты. После записи регистра продолжают выполняться обработчики подписок на события (ПриЗаписи, ОбработкаПроведения), а также каскадный пересчет зависимых и динамических видов цен.

Шаг 1. Диагностика с помощью Замера производительности

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

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

  1. Откроем конфигуратор и запустим сеанс 1С в режиме отладки.
  2. В меню Отладчика включим Замер производительности.
  3. Запустим проведение документа или программную обработку.
  4. Остановим замер и проанализируем полученную таблицу вызовов по колонке суммарного времени выполнения.

Шаг 2. Разбиение массива данных на небольшие порции

Попытка записать 90 000 строк в один документ приводит к экспоненциальному росту нагрузки на дисковую подсистему и оперативную память. Опыт показывает, что разбиение единого массива на порции существенно сокращает суммарное время выполнения.

Посмотрим на сравнение: проведение одного документа на 90 000 строк может длиться часами из-за разрастания транзакции и объема сериализации, в то время как 9 документов по 10 000 строк (или 18 документов по 5 000 строк) обработаются суммарно значительно быстрее за счет уменьшения размеров транзакций.

Шаг 3. Использование режима загрузки данных

Если создание документа выполняется программно (например, при первоначальном заполнении цен или импорте из внешней системы), целесообразно отключить избыточные проверки и обработчики с помощью свойства ОбменДанными.Загрузка.

Рассмотрим пример кода:


ДокументОбъект = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
// Заполнение реквизитов и табличной части документа
// ...
ДокументОбъект.ОбменДанными.Загрузка = Истина;
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);

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

Шаг 4. Запись напрямую в регистр сведений без документа

Если сохранение документов проведения не является обязательным требованием бизнес-процесса или выполняется первичная загрузка прайс-листа, наиболее эффективным решением будет отказаться от объектной техники (документа) и записать данные напрямую в регистр сведений с помощью объекта РегистрСведенийНаборЗаписей.

Проанализируем пример прямой записи набором записей:


НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Период.Установить(ТекущаяДата());

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

НаборЗаписей.ОбменДанными.Загрузка = Истина;
НаборЗаписей.Записать(Ложь);

Прямая запись набором записей с включенным флагом Загрузка = Истина исключает накладные расходы на формирование табличных частей документов и передачу тяжелых контекстов деревьев значений между сервером и клиентом.

← На главную