При оптимизации высоконагруженных систем разработчики часто сталкиваются с парадоксальной ситуацией: штатный инструмент Замер производительности показывает, что код выполняется за считанные секунды, однако пользователь ждет завершения операции несколько минут. Особенно остро эта проблема проявляется при работе с тяжелыми документами, содержащими десятки тысяч строк (например, формы ввода бюджета или крупные заказы).
В этой статье мы подробно разберем, какие именно процессы остаются "за кадром" стандартного замера, почему возникает колоссальная разница во времени и как правильно диагностировать подобные узкие места.
Для начала выясним причину, по которой Замер производительности в принципе может ошибаться. Принцип работы этого инструмента основан на фиксации времени перехода от одной исполняемой строки кода 1С к другой. Он суммирует время работы интерпретатора 1С, но практически не учитывает то, что происходит "между строк" или во внутренних механизмах платформы, не представленных в модулях.
Если мы видим в замере 30 секунд, а реальное время составляет 7 минут, это означает, что 6,5 минут система тратит на операции, которые не являются "кодом" в понимании конфигуратора. Рассмотрим эти операции подробнее.
Одной из самых весомых причин задержек при работе с документами на 25 000 строк является передача данных между клиентом и сервером. Проанализируем ситуацию: когда вы нажимаете кнопку "Провести" на форме, весь объект (вместе со всеми строками табличных частей) должен отправиться на сервер.
Сериализация — это процесс преобразования внутренних структур данных платформы в формат, пригодный для передачи по сети (обычно XML или JSON). При огромном количестве строк этот процесс потребляет значительные ресурсы процессора и памяти. Замер производительности не учитывает время, затраченное на упаковку данных на стороне клиента и их распаковку на стороне сервера. Чем "тяжелее" форма (много реквизитов, специфические типы данных), тем дольше длится этот невидимый этап.
Проверим влияние этого фактора простым экспериментом: создадим на форме кнопку с пустым серверным вызовом:
&НаКлиенте
Процедура ТестПередачиДанных(Команда)
ПустойСерверныйВызов();
КонецПроцедуры
&НаСервере
Процедура ПустойСерверныйВызов()
// Здесь нет кода, но форма всё равно передается на сервер и обратно
КонецПроцедуры
Если вызов этой пустой процедуры занимает значительное время, значит, основной тормоз — именно объем контекста формы и время его сериализации.
Рассмотрим следующий важный момент: запись данных в СУБД. В 1С проведение документа всегда происходит в транзакции. Процедура ОбработкаПроведения — это лишь часть процесса. Когда выполнение кода выходит из этой процедуры, платформа инициирует фиксацию транзакции (Commit).
Именно в этот момент СУБД выполняет основной объем работы:
Поскольку фиксация транзакции происходит после завершения кода 1С, Замер производительности её просто не видит. Если документ делает 144 000 движений, как в рассматриваемом примере, СУБД может тратить несколько минут на финализацию записи, в то время как замер покажет, что код 1С отработал мгновенно.
Выясним причину замедления при записи движений. Платформа 1С хранит итоги регистров для ускорения получения остатков. Если документ записывает данные "задним числом" или в будущие периоды, платформа может инициировать пересчет итогов. Это платформенная операция, которая выполняется на уровне СУБД и не отображается в строчках кода модуля проведения.
Для оптимизации этого процесса рекомендуется:
УстановитьИспользованиеИтогов() для временного отключения итогов при массовой загрузке, если это допустимо.Проанализируем дополнительные механизмы платформы. При записи объекта 1С может выполнять следующие действия:
Эти действия инициируются платформой автоматически при вызове метода Записать() и не детализируются в замере производительности.
Если мы столкнулись с тем, что документ на 25 000 строк проводится слишком долго, а замер бесполезен, применим следующие стратегии:
Если бизнес-логика позволяет, перенесите хранение данных из табличной части документа в РегистрСведений. Это позволит:
Вместо стандартной записи из формы попробуем реализовать сохранение данных через процедуру с директивой &НаСервереБезКонтекста. В этом случае на сервер будет передаваться не вся форма целиком, а только структура с необходимыми данными. Это кратно сокращает время на сериализацию.
&НаСервереБезКонтекста
Процедура СохранитьДанныеДокумента(СсылкаНаДокумент, МассивСтрок)
// Логика записи данных напрямую в базу или через объект
КонецПроцедуры
Чтобы увидеть реальную картину происходящего на стороне СУБД, необходимо настроить Технологический журнал. Рассмотрим пример настройки для отслеживания долгих запросов и событий СУБД:
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\LOGS\SQL" history="24">
<event>
<eq property="Name" value="DBMSSQL"/>
<gt property="Duration" value="100000"/>
</event>
<event>
<eq property="Name" value="SDBL"/>
</event>
</log>
</config>
События DBMSSQL (или DBPOSTGRS) покажут реальное время выполнения SQL-запросов и команд COMMIT, которые "скрыты" от замера в конфигураторе.
Помните, что Замер производительности — это инструмент для поиска ошибок в алгоритмах (циклах, неоптимальных запросах внутри кода). Если же проблема кроется в объемах данных, транзакционных задержках или сетевом взаимодействии, необходимо использовать более глубокие инструменты анализа, такие как Технологический журнал и мониторинг ресурсов СУБД.