Замер производительности в Конфигураторе: как найти, что тормозит в коде
Содержание
Профайлер в 1С 8.3 называется «Замер производительности». Он запускается в Конфигураторе во время отладки: Отладка → Начать отладку (F5), затем в Конфигураторе Отладка → Замер производительности. Вы повторяете медленное действие в клиенте, останавливаете замер и получаете дерево строк кода с числом вызовов и временем каждой.
Это главный инструмент, чтобы понять, почему тормозит программа на уровне кода: какой модуль, какая строка, сколько раз. Для глубины уровня СУБД и блокировок к нему добавляют технологический журнал и профайлер самой СУБД. Обычно начинают с замера, а к остальным средствам переходят, когда он указывает на запрос или ожидание.
| Инструмент | Что показывает | Когда брать |
|---|---|---|
| Замер производительности (Конфигуратор) | Строки кода 1С, вызовы, время | Тормозит конкретное действие: проведение, открытие формы, отчёт |
| Показатели производительности клиента | Число серверных вызовов и объём трафика | Тормозит форма, особенно через интернет или RDP |
| Технологический журнал | Запросы СУБД, ожидания и конфликты блокировок | Медленно только у части пользователей, «плавающие» зависания |
| Профайлер СУБД (SQL Server Profiler, pg_stat_statements) | Текст SQL, план, чтения | Нужно понять, почему конкретный запрос медленный на уровне базы |
Подготовка: как запустить профайлер 1С на файловой и серверной базе
Файловая база
Здесь дополнительной настройки нет.
- Откройте базу в Конфигураторе.
- Нажмите F5 или выберите
Отладка → Начать отладкуи нужный клиент (обычно тонкий). - В открывшемся клиенте дойдите до места перед медленным действием.
- Переключитесь в Конфигуратор, выберите
Отладка → Замер производительности— замер пошёл. - Выполните медленное действие в клиенте один раз.
- Снова выберите
Отладка → Замер производительности— замер остановится, откроется окно результатов.
Включайте замер непосредственно перед действием. Если он идёт, пока вы открываете список и ищете документ, в результаты попадёт шум из открытия форм.
Клиент-серверная база
Чтобы профайлер видел серверный код (а это почти всё проведение и запросы), на сервере 1С должна быть разрешена отладка.
- 🖥️ Служба агента сервера
ragentдолжна быть запущена с ключом-debug. Его прописывают в параметрах запуска службы. - 🌐 В 8.3 есть два протокола отладки: TCP и HTTP. Для HTTP-отладки к ключу добавляют
-http, и работает отдельный сервер отладкиdbgs. - ⚙️ Протокол в Конфигураторе выбирается в параметрах (
Сервис → Параметры, вкладка про отладку). Он должен совпадать с тем, как запущен сервер.
Перезапуск службы агента оборвёт сеансы всех пользователей кластера. Делайте это в нерабочее время или на копии.
Отладка на рабочем сервере замедляет его и открывает возможность подключиться отладчиком к чужим сеансам. Правильный путь — копия базы на тестовом сервере с тем же объёмом данных. На пустой демобазе узкое место часто не воспроизводится вовсе.
Фоновые задания и регламентные
Код фоновых заданий выполняется в отдельном сеансе. Чтобы замер его увидел, откройте Отладка → Подключение и включите автоматическое подключение к фоновым заданиям. После этого замер захватывает и их строки.
Как читать результаты замера: дерево вызовов и основные метрики
Окно результатов — таблица по модулям и строкам. Ключевые колонки такие:
| Колонка | Смысл | Как пользоваться |
|---|---|---|
| Количество (Кол.) | Сколько раз выполнилась строка | Тысячи раз — признак кода в цикле |
| Время | Время строки вместе со всем, что она вызвала | Показывает «ветку», где теряется время |
| Чистое время | Время самой строки без вложенных вызовов | Показывает, где тратится по-настоящему |
| % / Чистый % | Доля от общего времени замера | Сортируйте по ней в первую очередь |
| Признак сервера | Где выполнялась строка: клиент или сервер | Помогает найти лишние серверные вызовы |
Порядок разбора
- Отсортируйте по «Чистому %» по убыванию. Первые 3–5 строк обычно дают 70–90% времени.
- Двойной щелчок по строке открывает модуль на этой строке.
- Смотрите на пару «Количество × время одного вызова». Строка, вызванная 1 раз за 4 секунды, и строка, вызванная 4000 раз по 1 мс, — это разные проблемы.
- Если высокое «Время», но маленькое «Чистое» — проблема глубже. Раскрывайте вызываемую процедуру.
Пример чтения
Проведение реализации идёт 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 раз, а время то 0,1 с, то 15 с — в зависимости от того, кто ещё работает.
Как проверить, что дело в блокировке
- 🔒 Включите в технологическом журнале события
TLOCK,TTIMEOUTиTDEADLOCK. Они покажут, кто кого ждал и на каком пространстве блокировок. - ⏱️ Ошибка со словами
Превышено максимальное время ожидания предоставления блокировки— прямой признак конфликта управляемых блокировок. - 🔁 Ошибка про взаимоблокировку (deadlock) значит, что две транзакции захватили ресурсы в разном порядке.
Что делать
- Убедитесь, что конфигурация работает в режиме управляемых блокировок. Это свойство корня конфигурации «Режим управления блокировкой данных».
- Сокращайте транзакцию: тяжёлые расчёты и чтение справочников выносите до начала записи.
- Блокируйте узко. Блокировка регистра остатков по номенклатуре и складу из документа лучше, чем блокировка всей таблицы.
- Захватывайте ресурсы в одном порядке во всех документах, чтобы не было взаимоблокировок.
- Тяжёлые регламентные операции (закрытие месяца , перепроведение) запускайте вне рабочего времени.
Типичные ошибки при работе с профайлером и как их избежать
Ещё три промаха
- Чинят то, что медленно «на вид». Переписывают запрос, а 80% времени — в цикле с обращением через точку. Всегда начинайте с сортировки по чистому времени.
- Не делают замер «после». Без второго замера нельзя сказать, что исправление помогло. Сохраните оба результата и сравните одну и ту же строку.
- Замеряют в отладке и делают выводы об абсолютных цифрах. Отладка добавляет накладные расходы. Сравнивайте доли и количество вызовов, а не миллисекунды.
Частые вопросы о профайлере 1С
Можно ли сохранить результаты замера и открыть позже?
Работает ли замер производительности без доступа к Конфигуратору?
Ctrl+Shift+Alt+P): они покажут число серверных вызовов, но не строки кода.