При активном росте информационной базы и накоплении десятков миллионов записей в регистрах партионного учета (например, ПартииТоваровНаСкладахУпр, ПартииТоваровНаСкладахБух) время проведения документов может существенно деградировать. Нередко операция записи движений занимает до 70–80% от общего времени транзакции проведения. Разберем по шагам ключевые причины замедления и эффективные способы оптимизации работы с регистрами накопления.
Проанализируем типовую проблему партионного учета: при оперативном проведении документа система одновременно выполняет проверку остатков, подбор партий по алгоритмам FIFO/LIFO, расчет себестоимости и запись движений сразу в несколько тяжелых регистров. Это приводит к длительным транзакциям и высокой нагрузке на СУБД.
Для кардинального ускорения проведения документов рассмотрим следующие архитектурные шаги:
Выясним причину, связанную с таблицами итогов СУБД. При записи набора записей в регистр накопления СУБД обновляет не только основную таблицу движений, но и агрегатную таблицу итогов. Если дата документа позже периода рассчитанных итогов, платформа вынуждена вычислять и накладывать дельту движений относительно устаревшей точки итогов.
Посмотрим на правила работы с итогами:
ГраницаИтогов = КонецМесяца(ТекущаяДата());
РегистрыНакопления.ПартииТоваровНаСкладахУпр.УстановитьПериодРассчитанныхИтогов(ГраницаИтогов);
РегистрыНакопления.ПартииТоваровНаСкладахБух.УстановитьПериодРассчитанныхИтогов(ГраницаИтогов);
РегистрыНакопления.ПартииТоваровНаСкладахНал.УстановитьПериодРассчитанныхИтогов(ГраницаИтогов);
В регистрах партий из-за погрешностей округления или пересортицы по сериям и складам со временем накапливаются записи с нулевым количеством и ненулевой суммой (или наоборот). Такие строки навсегда остаются в таблице итогов регистра накопления (_AccumRgT), замедляя каждую операцию INSERT и UPDATE.
Рассмотрим порядок очистки:
При одновременной записи движений несколькими пользователями в одни и те же таблицы итогов возникают конфликты блокировок. Включение механизма разделения итогов позволяет платформе записывать итоги с добавлением случайного разделителя, распределяя нагрузку между параллельными потоками.
Разберем по шагам настройку разделения итогов:
РегистрыНакопления.ПартииТоваровНаСкладахУпр.УстановитьИспользованиеРазделителяИтогов(Истина);
РегистрыНакопления.ПартииТоваровНаСкладахБух.УстановитьИспользованиеРазделителяИтогов(Истина);
Посмотрим на настройки на уровне сервера базы данных, напрямую влияющие на скорость операций записи больших массивов данных:
.mdf), журнал транзакций (.ldf) и системную базу tempdb необходимо размещать на раздельных быстрых накопителях (SSD/NVMe). Это исключает конкуренцию за очередь диска при синхронной фиксации транзакций.UPDATE STATISTICS) с высокой выборкой. Сильная фрагментация индексов в таблицах движений резко увеличивает время физической записи страниц.Max Degree of Parallelism = 1 (или настроить порог Cost Threshold for Parallelism), чтобы исключить накладные расходы на межпоточную синхронизацию и блокировки CXPACKET при записи движений.Perform volume maintenance tasks исключает задержки записи при авторасширении файлов базы данных.Проанализируем код проведения документов. Если документ перепроводится без изменения состава номенклатуры и сумм, полная перезапись набора записей регистра создает избыточную нагрузку на СУБД (вызовы DELETE и INSERT).
Рекомендуется использовать сверку существующих движений перед записью или устанавливать свойство набора записей Записывать = Ложь, если пересчет движений не требуется.