Как ускорить выполнение метода Объект.Движения.Записать() в 1С:ERP?

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

При работе с крупными конфигурациями, такими как 1С:ERP Управление предприятием, разработчики часто сталкиваются с проблемой долгого проведения документов. Ситуация, когда замер производительности показывает десятки секунд на строке Объект.Движения.Записать(), является классической для систем с большим объемом данных и сложной логикой взаиморасчетов. Рассмотрим подробно, почему это происходит и как мы можем оптимизировать этот процесс.

1. Первичная диагностика через замер производительности

Прежде всего, проанализируем ситуацию с помощью встроенных инструментов. Если замер показывает, что основное время уходит на запись движений одного конкретного регистра (например, РегистрНакопления.РасчетыСКлиентами), нам необходимо выяснить количество обращений к базе данных. В рассматриваемом случае было зафиксировано более 34 000 операций вставки и обновления в таблицу итогов AccumRgT29391. Это явно указывает на то, что система пересчитывает огромный пласт данных при записи всего одного документа.

2. Проблема "кривых" дат в регистре

Одной из наиболее частых причин аномального замедления записи итогов является наличие записей с некорректными датами (далекое прошлое или далекое будущее). Выясним причину: когда в регистр попадает запись, например, с датой 3021 год, система при каждом последующем проведении документа пытается актуализировать итоги вплоть до этой даты.

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


ВЫБРАТЬ МИНИМУМ(Период), МАКСИМУМ(Период)
ИЗ РегистрНакопления.РасчетыСКлиентами

Если вы обнаружите даты, значительно отличающиеся от текущего рабочего периода, их необходимо исправить. Даже одна запись с пустой датой или датой из будущего может заставить SQL-сервер выполнять тысячи лишних операций при обновлении таблицы итогов AccumRgT.

3. Механизм онлайн-взаиморасчетов в 1С:ERP

В современных редакциях ERP (начиная с 2.4) реализован механизм "Онлайн-взаиморасчеты". Разберем по шагам, как он влияет на производительность:

  1. При записи движений по основным регистрам (Расчеты с клиентами / поставщиками), система может инициировать немедленный пересчет распределения оплат по документам и этапам.
  2. Если в настройках системы выбран вариант "Распределять взаиморасчеты при проведении", то Объект.Движения.Записать() будет ждать, пока выполнится вся цепочка распределения по ФИФО для данного объекта расчетов.
  3. Если по конкретному договору или заказу накоплено тысячи документов, пересчет станет крайне тяжелым.

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

4. Управление итогами и техническое обслуживание SQL

Проанализируем состояние таблиц итогов на уровне СУБД. Таблица AccumRgT (таблица итогов) страдает от фрагментации индексов сильнее других из-за постоянных обновлений. Выясним, когда в последний раз выполнялись регламентные операции.

Рассмотрим шаги по технической оптимизации:

  1. Пересчет итогов: Выполните полное обновление итогов через конфигуратор или консоль администрирования. Это пересчитает агрегаты и может существенно ускорить чтение/запись.
  2. Установка периода рассчитанных итогов: Убедитесь, что итоги рассчитаны по текущую дату. Если рассчитанные итоги "отстают" от периода проводимых документов, система будет вычислять остатки "на лету", используя таблицу движений, что гораздо медленнее.
  3. Обслуживание индексов: Выполните REBUILD индексов для таблиц конкретного регистра. Это позволит SQL-серверу эффективнее находить нужные страницы данных при обновлении.

5. Проверка режима разделения итогов

В свойствах регистра накопления существует свойство РазделениеИтогов. Посмотрим на его влияние:

Если разделение включено, система создает дополнительные записи в таблице итогов для разных сеансов, чтобы избежать блокировок. Однако, если количество "разделителей" становится слишком большим, а процедура слияния итогов не запускается вовремя, это может замедлить запись. Попробуем в качестве эксперимента временно отключить итоги для регистра и замерить скорость записи. Если время сократится до долей секунды — проблема 100% в обслуживании или данных таблицы итогов.

6. Использование Технологического Журнала (ТЖ)

Если вышеуказанные способы не помогают, проанализируем ситуацию с помощью Технологического Журнала. Настроим сбор событий 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% случаев проблема кроется либо в огромной цепочке пересчета онлайн-взаиморасчетов, либо в поврежденных/неактуальных итогах регистра накопления.

← На главную