Привет! В этой статье рассмотрим различные идеи оптимизации регистров накопления в 1С, чтобы закрытие месяца проходило гладко и база не ложилась под нагрузкой. Рассмотрим итоги, агрегаты и разделение итогов, а также пару трюков с делением данных по периодам.
Закрытие месяца в 1С обычно означает выполнение серии тяжелых расчетов: расчет себестоимости, распределение расходов, переоценка товаров — все это активно читает и пишет данные регистров накопления. Если регистры не оптимизированы, запросы могут перебирать миллионы записей, а записи блокировать друг друга. Все этов лучшем случае, часы ожидания. В худшем база может упаст.
Итоги регистров
Итоги — это суммарные данные регистра, которые платформа 1С хранит автоматически для ускорения запросов. Помимо таблицы движений регистр имеет таблицу итогов, где хранятся накопленные суммы ресурсов по ключевым измерениям на каждый месяц. Благодаря этому большинству отчетов не нужно пробегать по всем записям, они берут готовые цифры из итогов.
Звучит здорово, но расчет этих итогов требует дополнительной работы при каждом проведении документов. Когда вы проводите документ, платформа обновляет соответствующие записи в таблице итогов. Если документов много, особенно если вводятся они пачками, то обновление итогов может тормозить проведение.
С дает возможность отключать авторассчет итогов. Например, при массовой загрузке данных можно временно выключить использование итогов для регистра, тогда новые движения записываются быстрее. Сделать это можно программно:
// Выключаем авторасчет итогов перед массовой загрузкой РегистрыНакопления.ПартииТоваров.УстановитьИспользованиеИтогов(Ложь); // ... здесь выполняется загрузка большого количества движений ... // Включаем расчет итогов обратно (при этом система пересчитает итоги заново) РегистрыНакопления.ПартииТоваров.УстановитьИспользованиеИтогов(Истина);
При включении назад произойдет пересчет итогов с момента, когда мы их отключили. Пока итоги отключены, любые обращения к ним невозможны, платформа просто бросит ошибку несогласованности данных.
В обычной ежедневной работе лучше держать итоги включенными, чтобы пользователи получали быстрые отчеты и запросы. Индексы помогают быстро выбирать данные итогов. Если измерений очень много, индекс по всем сразу не построится (у MS SQL есть ограничение не более 16 столбцов в индексе). В таких случаях стоит пересмотреть модель данных или добавить агрегаты, что подводит нас к следующему разделу.
Агрегаты
Агрегаты — это специальный механизм 1С для повышения производительности оборотных регистров. По сути, агрегат — такое вот специализированное хранилище в виде отдельной таблицы, где хранятся сводные обороты ресурсов регистра по выбранным измерениям с заданной периодичностью.
Зачем это может понадобиться? Представьте, что есть отчет, который строится помесячно и по отдельным параметрам, которых нет в стандартных ежемесячных итогах. Без агрегатов запрос лезет в таблицу движений и агрегирует на ходу. А с правильно настроенным агрегатом данные уже предсчитаны. Агрегаты могут сократить время выполнения таких запросов.
Однако бесплатного ускорения не бывает: агрегаты нужно поддерживать актуальными. Как это делается:
В конфигураторе задаем, по каким измерениям и с какой периодичностью строить агрегаты. Можно сделать это вручную, а можно довериться платформе,вызвать метод
ОпределитьОптимальныеАгрегаты(), и 1С сама предложит набор агрегатов на основе статистики запросов.По дефолту 1С продолжает использовать обычные итоги. Чтобы переключиться на агрегаты, надо программно включить режим агрегатов для регистра:
// Включаем использование агрегатов для регистра РегистрыНакопления.МойОборотныйРегистр.УстановитьРежимАгрегатов();С этого момента запросы к регистру будут использовать данные агрегатов (если найдут подходящий) вместо таблицы итогов.
Нужно регулярно (например, раз в час или по расписанию ночью) выполнять метод
ОбновитьАгрегаты(). Он переносит накопившиеся новые движения из основной таблицы регистра в соответствующие таблицы агрегатов. Переносятся только движения, появившиеся после предыдущего обновления.Время от времени (скажем, раз в месяц) стоит пересчитывать оптимальный список агрегатов методом
ПерестроитьИспользованиеАгрегатов().
Конечно, все эти операции желательно выполнять в периоды минимальной нагрузки.
Разделение итогов
Теперь поговорим про разделение итогов. Если несколько документов одновременно пишут в один и тот же регистр с одинаковыми ключами (значениями измерений), они обычно конфликтуют. Платформа при записи блокирует строки итогов по комбинации измерений, чтобы пересчитать их, и второй документ ждет, пока первый завершится. Разделение итогов может снять это ограничение.
В таблицу итогов добавляется специальное техническое поле‑разделитель. Когда два документа пытаются записать одинаковый ключ, 1С создает две записи итогов с разными значениями разделителя вместо одной общей. За счет этого блокировки практически не пересекаются, и документы проводятся параллельно.
Однако применять разделение итогов нужно с умом. Во‑первых, прирост будет только если действительно есть параллельная запись в один регистр. Если документы, как правило, проводятся последовательно или их мало, эффекта не будет. Во‑вторых, если по регистру включен контроль остатков (например, недопущение отрицательного остатка товара), то толку от разделения итогов не будет. При контроле остатков 1С все равно блокирует данные регистра без учета разделителя (иначе проверка была бы некорректной), и параллельности не выйдет.
В конфигураторе для каждого регистра есть свойство «Разрешить разделение итогов». По умолчанию для новых регистров оно включено. Но само по себе наличие свойства ничего не меняет, если его программно не задействовать. В пользовательском режиме (через стандартную обработку «Управление итогами») или кодом можно включать/выключать разделение на лету:
// Включить режим разделения итогов для регистра РегистрыНакопления.МойРегистр.УстановитьРежимРазделенияИтогов(Истина);
Попробуйте проанализировать, где у вас узкие места по блокировкам. Если есть подозрение, что регистр «распирает» от одновременных записей — смело экспериментируйте с этой настройкой на тестовой базе. Т��лько убедитесь, что нигде не страдает контроль остатков, как мы обсудили.
Архивирование старых периодов
Пару слов о разделении данных по периодам. Часто тормоза при закрытии месяца связаны не только с текущим объемом документов, но и с грузом прошлых лет. База разрастается, регистры содержат движения за 5,7,10 лет, и каждый запрос вынужден шуровать по древним слоям истории.
Решение — архивировать старые периоды. В 1С для этого существует процедура свертки информационной базы. Смысл свертки: объединить (свернуть) все движения до определенной даты (например, до начала текущего года) и сохранить только начальные остатки. Все подробные записи за прошлые годы удаляются, заменяясь несколькими записями остатков на 01.01.xxxx. Размер базы сокращается, и все расчеты за текущий год существенно ускоряются.
Конечно, свертка — крайний случай.

Если упираетесь в регистры, итоги и блокировки на закрытии месяца, это уже зона ответственности архитектора. На курсе «Архитектор 1С» разбирают, как проектировать архитектуру 1С, выстраивать DevOps-контур и интеграции (Kafka/RMQ) так, чтобы производительность под нагрузкой была свойством системы, а не удачей. Готовы к серьезному обучению? Пройдите вступительный тест.
Для знакомства с форматом обучения и экспертами приходите на бесплатные демо-уроки:
10 февраля, 19:00. «Правильная разработка по GitFlow в 1С:EDT». Записаться
19 февраля, 20:00. «ИТ-конвейер 1С на EvaDev». Записаться
Больше открытых уроков смотрите в посте.
