Как увеличить скорость записи в регистры и проведения документов в 1С?

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

При активном росте информационной базы и накоплении десятков миллионов записей в регистрах партионного учета (например, ПартииТоваровНаСкладахУпр, ПартииТоваровНаСкладахБух) время проведения документов может существенно деградировать. Нередко операция записи движений занимает до 70–80% от общего времени транзакции проведения. Разберем по шагам ключевые причины замедления и эффективные способы оптимизации работы с регистрами накопления.

1. Перенос расчета себестоимости и списания партий в фоновый режим

Проанализируем типовую проблему партионного учета: при оперативном проведении документа система одновременно выполняет проверку остатков, подбор партий по алгоритмам FIFO/LIFO, расчет себестоимости и запись движений сразу в несколько тяжелых регистров. Это приводит к длительным транзакциям и высокой нагрузке на СУБД.

Для кардинального ускорения проведения документов рассмотрим следующие архитектурные шаги:

  1. Отключение списания партий при оперативном проведении. В настройках параметров учета отключается флаг списания партий при проведении документов. Документ формирует только оперативные количественные движения по складским регистрам и взаиморасчетам, проводясь за доли секунды.
  2. Регламентное списание партий. Расчет суммовой себестоимости и формирование движений по партионным регистрам выносятся в регламентное задание (обработка «Проведение по партиям»), которое выполняется в фоновом режиме по расписанию или в технологические окна (ночью).
  3. Использование отложенного проведения. Если полное разделение невозможно, применяется механизм отложенного проведения, при котором тяжелые расчеты выносятся в отдельную очередь фоновых заданий.

2. Управление периодом рассчитанных итогов регистров

Выясним причину, связанную с таблицами итогов СУБД. При записи набора записей в регистр накопления СУБД обновляет не только основную таблицу движений, но и агрегатную таблицу итогов. Если дата документа позже периода рассчитанных итогов, платформа вынуждена вычислять и накладывать дельту движений относительно устаревшей точки итогов.

Посмотрим на правила работы с итогами:

  1. Сдвиг границы итогов вперед. Период рассчитанных итогов должен быть установлен минимум на конец текущего месяца (а лучше — на конец следующего). Это минимизирует накладные расходы платформы при модификации агрегатов.
  2. Программная установка границы итогов. Для автоматизации поддержания актуальности итогов настроим регламентное задание, выполняющее вызов метода платформы:

ГраницаИтогов = КонецМесяца(ТекущаяДата());
РегистрыНакопления.ПартииТоваровНаСкладахУпр.УстановитьПериодРассчитанныхИтогов(ГраницаИтогов);
РегистрыНакопления.ПартииТоваровНаСкладахБух.УстановитьПериодРассчитанныхИтогов(ГраницаИтогов);
РегистрыНакопления.ПартииТоваровНаСкладахНал.УстановитьПериодРассчитанныхИтогов(ГраницаИтогов);

3. Очистка таблиц итогов от «зависших нулей» и пересчет

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

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

  1. Выполнить регулярную процедуру «Тестирование и исправление» с обязательным включением пункта «Пересчет итогов».
  2. Выявить с помощью отчетов или запросов зависшие остатки по партиям и скорректировать их специализированными корректирующими документами, чтобы свести нулевые остатки в таблице итогов к нулю по всем разрезам.

4. Включение разделения итогов для регистров накопления

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

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

  1. В конфигураторе в свойствах регистра накопления установим флаг «Разрешить разделение итогов».
  2. В режиме 1С:Предприятие включим использование разделителя программно или через регламентное задание:

РегистрыНакопления.ПартииТоваровНаСкладахУпр.УстановитьИспользованиеРазделителяИтогов(Истина);
РегистрыНакопления.ПартииТоваровНаСкладахБух.УстановитьИспользованиеРазделителяИтогов(Истина);
  1. Для поддержания оптимальной скорости чтения отчетов настроим регулярное регламентное задание «Слияние итогов» во внерабочее время.

5. Оптимизация СУБД и дисковой подсистемы (MS SQL Server)

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

  1. Разнесение файлов по физическим дискам. Файлы базы данных (.mdf), журнал транзакций (.ldf) и системную базу tempdb необходимо размещать на раздельных быстрых накопителях (SSD/NVMe). Это исключает конкуренцию за очередь диска при синхронной фиксации транзакций.
  2. Регламентные процедуры SQL. Настроим регулярное обслуживание базы: перестроение (rebuild) или реорганизацию (reorganize) индексов, а также обновление статистики (UPDATE STATISTICS) с высокой выборкой. Сильная фрагментация индексов в таблицах движений резко увеличивает время физической записи страниц.
  3. Ограничение степени параллелизма (MAXDOP). На экземпляре MS SQL Server рекомендуется установить параметр Max Degree of Parallelism = 1 (или настроить порог Cost Threshold for Parallelism), чтобы исключить накладные расходы на межпоточную синхронизацию и блокировки CXPACKET при записи движений.
  4. Мгновенная инициализация файлов. Предоставление службе SQL Server права Perform volume maintenance tasks исключает задержки записи при авторасширении файлов базы данных.

6. Оптимизация алгоритмов записи в программном коде

Проанализируем код проведения документов. Если документ перепроводится без изменения состава номенклатуры и сумм, полная перезапись набора записей регистра создает избыточную нагрузку на СУБД (вызовы DELETE и INSERT).

Рекомендуется использовать сверку существующих движений перед записью или устанавливать свойство набора записей Записывать = Ложь, если пересчет движений не требуется.

← На главную