При работе с крупными конфигурациями, такими как 1С:ERP Управление предприятием, разработчики часто сталкиваются с проблемой долгого проведения документов. Ситуация, когда замер производительности показывает десятки секунд на строке Объект.Движения.Записать(), является классической для систем с большим объемом данных и сложной логикой взаиморасчетов. Рассмотрим подробно, почему это происходит и как мы можем оптимизировать этот процесс.
Прежде всего, проанализируем ситуацию с помощью встроенных инструментов. Если замер показывает, что основное время уходит на запись движений одного конкретного регистра (например, РегистрНакопления.РасчетыСКлиентами), нам необходимо выяснить количество обращений к базе данных. В рассматриваемом случае было зафиксировано более 34 000 операций вставки и обновления в таблицу итогов AccumRgT29391. Это явно указывает на то, что система пересчитывает огромный пласт данных при записи всего одного документа.
Одной из наиболее частых причин аномального замедления записи итогов является наличие записей с некорректными датами (далекое прошлое или далекое будущее). Выясним причину: когда в регистр попадает запись, например, с датой 3021 год, система при каждом последующем проведении документа пытается актуализировать итоги вплоть до этой даты.
Проанализируем состояние данных в регистре с помощью простого запроса:
ВЫБРАТЬ МИНИМУМ(Период), МАКСИМУМ(Период)
ИЗ РегистрНакопления.РасчетыСКлиентами
Если вы обнаружите даты, значительно отличающиеся от текущего рабочего периода, их необходимо исправить. Даже одна запись с пустой датой или датой из будущего может заставить SQL-сервер выполнять тысячи лишних операций при обновлении таблицы итогов AccumRgT.
В современных редакциях ERP (начиная с 2.4) реализован механизм "Онлайн-взаиморасчеты". Разберем по шагам, как он влияет на производительность:
Объект.Движения.Записать() будет ждать, пока выполнится вся цепочка распределения по ФИФО для данного объекта расчетов.Для оптимизации рекомендуется переключить настройку в режим "Фоновым заданием". В этом случае документ будет проводиться мгновенно, а тяжелые расчеты по распределению остатков выполнит отдельный фоновый процесс, не блокируя работу пользователя.
Проанализируем состояние таблиц итогов на уровне СУБД. Таблица AccumRgT (таблица итогов) страдает от фрагментации индексов сильнее других из-за постоянных обновлений. Выясним, когда в последний раз выполнялись регламентные операции.
Рассмотрим шаги по технической оптимизации:
REBUILD индексов для таблиц конкретного регистра. Это позволит SQL-серверу эффективнее находить нужные страницы данных при обновлении.В свойствах регистра накопления существует свойство РазделениеИтогов. Посмотрим на его влияние:
Если разделение включено, система создает дополнительные записи в таблице итогов для разных сеансов, чтобы избежать блокировок. Однако, если количество "разделителей" становится слишком большим, а процедура слияния итогов не запускается вовремя, это может замедлить запись. Попробуем в качестве эксперимента временно отключить итоги для регистра и замерить скорость записи. Если время сократится до долей секунды — проблема 100% в обслуживании или данных таблицы итогов.
Если вышеуказанные способы не помогают, проанализируем ситуацию с помощью Технологического Журнала. Настроим сбор событий DBMSSQL, чтобы увидеть реальные SQL-запросы, которые отправляет платформа. Рассмотрим пример настройки logcfg.xml для отслеживания долгих запросов:
<event query="DBMSSQL">
<property name="all"/>
<filter>
<condition column="duration" variant="ge" value="100000"/>
</filter>
</event>
Это позволит увидеть, на какой именно таблице "спотыкается" SQL-сервер и нет ли там избыточных блокировок (WaitConnections), которые могут возникать при записи движений.
Для ускорения метода Записать() в 1С:ERP необходимо действовать комплексно: сначала исключить влияние "плохих" дат в данных, затем проверить настройки распределения взаиморасчетов (перевести в фон) и в завершение провести регламентные операции с итогами и индексами на стороне SQL-сервера. Как показывает практика, в 90% случаев проблема кроется либо в огромной цепочке пересчета онлайн-взаиморасчетов, либо в поврежденных/неактуальных итогах регистра накопления.