Замер производительности в Конфигураторе: как найти, что тормозит в коде

· 9 мин

Содержание

Профайлер в 1С 8.3 называется «Замер производительности». Он запускается в Конфигураторе во время отладки: Отладка → Начать отладку (F5), затем в Конфигураторе Отладка → Замер производительности. Вы повторяете медленное действие в клиенте, останавливаете замер и получаете дерево строк кода с числом вызовов и временем каждой.

Это главный инструмент, чтобы понять, почему тормозит программа на уровне кода: какой модуль, какая строка, сколько раз. Для глубины уровня СУБД и блокировок к нему добавляют технологический журнал и профайлер самой СУБД. Обычно начинают с замера, а к остальным средствам переходят, когда он указывает на запрос или ожидание.

ИнструментЧто показываетКогда брать
Замер производительности (Конфигуратор)Строки кода 1С, вызовы, времяТормозит конкретное действие: проведение, открытие формы, отчёт
Показатели производительности клиентаЧисло серверных вызовов и объём трафикаТормозит форма, особенно через интернет или RDP
Технологический журналЗапросы СУБД, ожидания и конфликты блокировокМедленно только у части пользователей, «плавающие» зависания
Профайлер СУБД (SQL Server Profiler, pg_stat_statements)Текст SQL, план, чтенияНужно понять, почему конкретный запрос медленный на уровне базы

Подготовка: как запустить профайлер 1С на файловой и серверной базе

Файловая база

Здесь дополнительной настройки нет.

  1. Откройте базу в Конфигураторе.
  2. Нажмите F5 или выберите Отладка → Начать отладку и нужный клиент (обычно тонкий).
  3. В открывшемся клиенте дойдите до места перед медленным действием.
  4. Переключитесь в Конфигуратор, выберите Отладка → Замер производительности — замер пошёл.
  5. Выполните медленное действие в клиенте один раз.
  6. Снова выберите Отладка → Замер производительности — замер остановится, откроется окно результатов.

Включайте замер непосредственно перед действием. Если он идёт, пока вы открываете список и ищете документ, в результаты попадёт шум из открытия форм.

Клиент-серверная база

Чтобы профайлер видел серверный код (а это почти всё проведение и запросы), на сервере 1С должна быть разрешена отладка.

  • 🖥️ Служба агента сервера ragent должна быть запущена с ключом -debug. Его прописывают в параметрах запуска службы.
  • 🌐 В 8.3 есть два протокола отладки: TCP и HTTP. Для HTTP-отладки к ключу добавляют -http, и работает отдельный сервер отладки dbgs.
  • ⚙️ Протокол в Конфигураторе выбирается в параметрах (Сервис → Параметры, вкладка про отладку). Он должен совпадать с тем, как запущен сервер.

Перезапуск службы агента оборвёт сеансы всех пользователей кластера. Делайте это в нерабочее время или на копии.

Отладка на рабочем сервере замедляет его и открывает возможность подключиться отладчиком к чужим сеансам. Правильный путь — копия базы на тестовом сервере с тем же объёмом данных. На пустой демобазе узкое место часто не воспроизводится вовсе.

Фоновые задания и регламентные

Код фоновых заданий выполняется в отдельном сеансе. Чтобы замер его увидел, откройте Отладка → Подключение и включите автоматическое подключение к фоновым заданиям. После этого замер захватывает и их строки.

Как читать результаты замера: дерево вызовов и основные метрики

Окно результатов — таблица по модулям и строкам. Ключевые колонки такие:

КолонкаСмыслКак пользоваться
Количество (Кол.)Сколько раз выполнилась строкаТысячи раз — признак кода в цикле
ВремяВремя строки вместе со всем, что она вызвалаПоказывает «ветку», где теряется время
Чистое времяВремя самой строки без вложенных вызововПоказывает, где тратится по-настоящему
% / Чистый %Доля от общего времени замераСортируйте по ней в первую очередь
Признак сервераГде выполнялась строка: клиент или серверПомогает найти лишние серверные вызовы

Порядок разбора

  1. Отсортируйте по «Чистому %» по убыванию. Первые 3–5 строк обычно дают 70–90% времени.
  2. Двойной щелчок по строке открывает модуль на этой строке.
  3. Смотрите на пару «Количество × время одного вызова». Строка, вызванная 1 раз за 4 секунды, и строка, вызванная 4000 раз по 1 мс, — это разные проблемы.
  4. Если высокое «Время», но маленькое «Чистое» — проблема глубже. Раскрывайте вызываемую процедуру.

Пример чтения

Проведение реализации идёт 6 секунд. В замере видим:

  • строка Запрос.Выполнить() в модуле менеджера: 1 вызов, 0,4 с;
  • строка Номенклатура.ВидНоменклатуры.ВестиУчетПоСериям внутри цикла по товарам: 850 вызовов, 4,9 с;
  • остальное — 0,7 с.

Вывод: тормозит не запрос, а обращение к реквизиту через точку в цикле. Каждое такое обращение читает из базы объект целиком. 850 строк — 850 лишних чтений. Чинить нужно именно это место.

Ускорение кода по результатам замера: пример «до и после»

Вернёмся к примеру с проведением за 6 секунд. Медленный вариант выглядит так:

Для Каждого СтрокаТЧ Из Товары Цикл
	Если СтрокаТЧ.Номенклатура.ВидНоменклатуры.ВестиУчетПоСериям Тогда
		ПроверитьСерию(СтрокаТЧ);
	КонецЕсли;
КонецЦикла;

Каждая итерация дважды идёт в базу: за номенклатурой и за её видом. Быстрый вариант получает признак одним запросом для всех строк сразу:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|	Номенклатура.Ссылка КАК Номенклатура,
|	Номенклатура.ВидНоменклатуры.ВестиУчетПоСериям КАК ВестиУчетПоСериям
|ИЗ
|	Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|	Номенклатура.Ссылка В (&Список)";
Запрос.УстановитьПараметр("Список", Товары.ВыгрузитьКолонку("Номенклатура"));

СПериями = Новый Соответствие;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
	СПериями.Вставить(Выборка.Номенклатура, Выборка.ВестиУчетПоСериям);
КонецЦикла;

Для Каждого СтрокаТЧ Из Товары Цикл
	Если СПериями[СтрокаТЧ.Номенклатура] = Истина Тогда
		ПроверитьСерию(СтрокаТЧ);
	КонецЕсли;
КонецЦикла;

Имена справочника и реквизитов здесь условные — подставьте свои. Суть приёма не меняется: одно обращение к базе вместо сотен.

После правки повторите замер на том же документе. В нашем примере строка с циклом должна исчезнуть из верхних строк по чистому времени, а число вызовов чтения упадёт с 850 до одного запроса. Если время проведения снизилось, но в лидерах появилась другая строка — это нормально: теперь видно следующее узкое место.

Другие частые находки

  • 📝 Запись объекта в цикле (Объект.Записать() сотни раз) — по возможности пишите набором записей регистра за один раз.
  • 🔎 НайтиПоНаименованию и НайтиПоРеквизиту в цикле — заменяйте одним запросом с соответствием, как выше.
  • 🧮 Тяжёлый расчёт в ПриПолученииДанныхНаСервере динамического списка — обработчик срабатывает на каждую порцию строк при прокрутке.

Медленные запросы: от профайлера 1С к базе данных

Профайлер показывает время строки Запрос.Выполнить(), но не объясняет, почему запрос медленный. Причины ищут так.

Что проверить в тексте запроса

  • 🔁 Запрос в цикле. Если строка Выполнить() вызвана сотни раз — соберите один пакетный запрос с параметром-списком или временной таблицей.
  • 🔗 Разыменование составных полей. Обращение Регистратор.Дата или к полю составного типа порождает соединения со всеми таблицами типа. Используйте ВЫРАЗИТЬ(... КАК Документ.РеализацияТоваровУслуг).
  • 📊 Виртуальные таблицы без параметров. Условие в ГДЕ вместо параметров Остатки(&Период, Номенклатура В (&Список)) заставляет считать остатки по всей базе, а потом фильтровать.
  • 🧩 Подзапросы в условиях соединения. Чаще всего выгоднее вынести их во временную таблицу и проиндексировать её (ИНДЕКСИРОВАТЬ ПО).
  • 🚫 Условие ИЛИ по разным полям. Мешает СУБД использовать индекс; иногда помогает разбивка на ОБЪЕДИНИТЬ ВСЕ.

Как увидеть SQL и план

Для этого нужен технологический журнал: файл logcfg.xml в каталоге conf платформы. В нём включают события DBMSSQL (для MS SQL) или DBPOSTGRS (для PostgreSQL) с отбором по длительности. Тогда в журнал попадут только тяжёлые запросы с текстом SQL.

На стороне СУБД помогают свои средства: SQL Server Profiler или Extended Events в MS SQL, расширение pg_stat_statements в PostgreSQL. Когда говорят «профайлер 1С» в контексте SQL, иногда имеют в виду именно их.

Ставьте отбор по длительности в техжурнале, например от 1 секунды. Без отбора журнал за час работы базы на 50 пользователей вырастает до гигабайт.

Оптимизация клиент-серверного взаимодействия

Если в замере много строк с переходом на сервер, а их чистое время мало, проблема в количестве вызовов. Каждый серверный вызов — это сетевая задержка. В локальной сети это 1–5 мс, через интернет или VPN — 50–150 мс. Двадцать вызовов при открытии формы через VPN — уже 1–3 секунды ожидания.

Как посчитать вызовы

В клиенте включите показатели производительности: сочетание Ctrl+Shift+Alt+P. Появится панель с числом серверных вызовов, временем и объёмом переданных данных для последнего действия. Сравните цифры до и после исправления.

Что исправлять

  1. Объединяйте вызовы. Три подряд вызова &НаСервере из одного клиентского обработчика сводите в одну серверную процедуру, которая вернёт все нужные данные.
  2. Используйте &НаСервереБезКонтекста. Директива &НаСервере передаёт на сервер и обратно данные формы. Если процедуре форма не нужна, без контекста вызов легче.
  3. Не тяните данные в обработчиках ПриИзменении по одному полю. Лучше получить пакет значений один раз.
  4. Кешируйте постоянные данные. Общие модули с повторным использованием возвращаемых значений («На время сеанса») убирают повторные чтения констант и настроек.
  5. Проверяйте ПриСозданииНаСервере. Тяжёлые запросы при открытии формы часто можно отложить до момента, когда пользователь их реально запросит.

Из модуля с повторным использованием не возвращайте изменяемые данные, которые пользователь может поменять в течение сеанса. Иначе он увидит устаревшее значение до перезапуска.

Блокировки и конкурентный доступ в замере производительности

Замер производительности не помечает ожидание блокировки отдельно. Если транзакция ждёт, пока другой пользователь отпустит данные, это время просто ляжет на строку записи или на Блокировка.Заблокировать(). Признак: строка выполняется 1 раз, а время то 0,1 с, то 15 с — в зависимости от того, кто ещё работает.

Как проверить, что дело в блокировке

  • 🔒 Включите в технологическом журнале события TLOCK, TTIMEOUT и TDEADLOCK. Они покажут, кто кого ждал и на каком пространстве блокировок.
  • ⏱️ Ошибка со словами Превышено максимальное время ожидания предоставления блокировки — прямой признак конфликта управляемых блокировок.
  • 🔁 Ошибка про взаимоблокировку (deadlock) значит, что две транзакции захватили ресурсы в разном порядке.

Что делать

  1. Убедитесь, что конфигурация работает в режиме управляемых блокировок. Это свойство корня конфигурации «Режим управления блокировкой данных».
  2. Сокращайте транзакцию: тяжёлые расчёты и чтение справочников выносите до начала записи.
  3. Блокируйте узко. Блокировка регистра остатков по номенклатуре и складу из документа лучше, чем блокировка всей таблицы.
  4. Захватывайте ресурсы в одном порядке во всех документах, чтобы не было взаимоблокировок.
  5. Тяжёлые регламентные операции (закрытие месяца , перепроведение) запускайте вне рабочего времени.

Типичные ошибки при работе с профайлером и как их избежать

Диагностика: выберите симптом

Ещё три промаха

  • Чинят то, что медленно «на вид». Переписывают запрос, а 80% времени — в цикле с обращением через точку. Всегда начинайте с сортировки по чистому времени.
  • Не делают замер «после». Без второго замера нельзя сказать, что исправление помогло. Сохраните оба результата и сравните одну и ту же строку.
  • Замеряют в отладке и делают выводы об абсолютных цифрах. Отладка добавляет накладные расходы. Сравнивайте доли и количество вызовов, а не миллисекунды.

Частые вопросы о профайлере 1С

Можно ли сохранить результаты замера и открыть позже?
Да. В окне результатов есть сохранение замера в файл и его загрузка. Так удобно сравнить замер до и после правки или передать результаты разработчику.
Работает ли замер производительности без доступа к Конфигуратору?
Нет. Нужен Конфигуратор с правами на отладку. Для пользователя без доступа к коду есть показатели производительности (Ctrl+Shift+Alt+P): они покажут число серверных вызовов, но не строки кода.
Покажет ли профайлер код в расширении конфигурации?
Да, если расширение подключено к базе. Строки модулей расширения попадают в замер так же, как основной конфигурации, с указанием модуля.
Можно ли замерять типовую конфигурацию на поддержке?
Можно. Замер ничего не меняет в коде. Снимать с поддержки для этого не нужно — правки потом лучше делать в расширении.
Чем замер производительности отличается от технологического журнала?
Замер — точечный инструмент на одно действие в одном сеансе, с привязкой к строкам кода. Техжурнал пишет события сервера и СУБД по всем сеансам и годится для «плавающих» проблем и блокировок.