Диагностика производительности 1С: ищем медленные запросы и блокировки
Содержание
«Строкатач» — не кнопка в меню и не отдельная программа. Так на форумах называют задачу: построчно проследить, какие запросы 1С гонит в базу, где она упирается в диск или процессор и кто держит блокировки. Решают эту задачу штатными средствами платформы — технологическим журналом, замером производительности и анализом блокировок.
Если база тормозит на бою у всех сразу — начинают с технологического журнала (ТЖ): он ловит длительные SQL-запросы, ожидания и взаимоблокировки прямо в рабочей среде. Если медленно работает одна обработка или отчёт — быстрее включить замер производительности в Конфигураторе: он покажет время по каждой строке кода. Трассировка запросов и поиск блокировок в 1С — это связка из нескольких инструментов, и ниже разберём, какой когда брать.
Что стоит за словом «строкатач» и какие инструменты есть в 1С
Диагностика делится на два уровня: что делает код 1С и что делает СУБД. Один инструмент обе стороны не закрывает, поэтому держат под рукой несколько.
| Инструмент | Что показывает | Когда брать |
|---|---|---|
| Технологический журнал (ТЖ) | длительные SQL-запросы, ожидания и взаимоблокировки на рабочей базе | тормозит в проде, нужны факты по реальной нагрузке |
| Замер производительности | время выполнения построчно по коду | медленно работает конкретная обработка или отчёт |
| Оценка производительности (APDEX) | насколько быстры ключевые операции «глазами пользователя» | постоянный мониторинг, SLA |
| Логи СУБД / Extended Events | запросы и планы на стороне MS SQL или PostgreSQL | глубокий разбор тяжёлого запроса |
Журнал регистрации (Администрирование → Журнал регистрации) для этой задачи не подходит: он фиксирует действия пользователей и ошибки, но не SQL-запросы и не блокировки. Путать его с технологическим журналом — частая ошибка новичка.
Построчная трассировка в чистом виде — это замер производительности: он разбирает исполняемый код на строки. ТЖ работает крупнее — по событиям (запрос, вызов, блокировка), но именно он видит то, что происходит на бою под реальными пользователями.
Как настроить технологический журнал
ТЖ включается текстовым файлом logcfg.xml. Его кладут в каталог conf каталога установки платформы — например, C:\Program Files\1cv8\conf\logcfg.xml. Для серверной базы файл размещают на том компьютере, где работает сервер 1С, рядом с процессом ragent.
Минимальный конфиг, который собирает длительные запросы и блокировки:
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="D:\tj_logs" history="4">
<event>
<ge property="Duration" value="3000000"/>
<eq property="Name" value="DBMSSQL"/>
</event>
<event>
<eq property="Name" value="TLOCK"/>
</event>
<event>
<eq property="Name" value="TTIMEOUT"/>
</event>
<event>
<eq property="Name" value="TDEADLOCK"/>
</event>
<property name="all"/>
</log>
</config>
Что здесь настроено:
- 📂
location— каталог, куда пишутся логи. Платформа создаёт в нём подпапки по процессам и файлы по часам. - ⏱
history— сколько часов хранить, старые файлы удаляются сами. - 🐌
DBMSSQLс фильтромDuration— ловим только длительные SQL-запросы. ЗначениеDurationзадаётся в микросекундах, поэтому3000000отбирает события примерно от 3 секунд. Единицы стоит сверить в описании технологического журнала и подстроить порог под себя. - 🔒
TLOCK,TTIMEOUT,TDEADLOCK— установка управляемой блокировки, ожидание на блокировке и взаимоблокировка.
Файл перечитывается платформой автоматически, перезапуск сервера не нужен. Чтобы выключить журнал — уберите или очистите logcfg.xml.
Пара настроек, которые сильно упрощают разбор:
- Чтобы вместе с запросом видеть его план выполнения, добавьте сбор соответствующего свойства события (
planSQLText). План сразу показывает сканирование таблиц и нехватку индексов — без него по тексту запроса причину видно не всегда. - Событие
SDBLфиксирует запрос на языке 1С, ещё до перевода в SQL. ПараSDBL+DBMSSQLодного времени помогает понять, какой именно запрос конфигурации превратился в тяжёлый SQL. - В клиент-серверном варианте журнал собирается на сервере 1С; в файловом — на компьютере, где запущена база. Для серверной базы не ищите логи на клиентской машине, их там нет.
Широкие фильтры (например, все события без порога по Duration) на нагруженной базе за минуты забивают диск гигабайтами логов и добавляют нагрузку. Включайте ТЖ узко, на короткое окно, и выключайте сразу после сбора данных. Диагностику лучше вести, когда воспроизводится проблема, а не «на всякий случай сутками».
Построчная трассировка кода через замер производительности
Когда виновник — конкретная обработка, отчёт или проведение документа, точнее всего работает замер производительности. Это и есть «строчная» трассировка: платформа покажет каждую строку кода, сколько раз она выполнялась и сколько времени заняла.
- Откройте базу в режиме Конфигуратор.
- Запустите
Сервис → Замер производительности. - Нажмите старт, выполните в пользовательском режиме ту операцию, что тормозит, вернитесь и остановите замер.
- В таблице отсортируйте строки по времени — сверху окажутся самые тяжёлые участки.
На что смотреть в результатах:
- строки с большим чистым временем — там и теряются секунды;
- вызовы в цикле: если одна строка выполнилась тысячи раз, проблема в алгоритме, а не в запросе;
- обращения к базе внутри цикла — типичный антипаттерн, запрос нужно выносить наружу и читать данные пачкой.
Замер отвечает на вопрос «где в коде теряется время», но не всегда — «почему». Если самой тяжёлой строкой оказался запрос, дальше его разбирают уже через технологический журнал и план выполнения. Так два инструмента работают в паре: замер сужает поиск до строки, ТЖ показывает, что эта строка делает на уровне базы.
Замер снимают на тестовой копии с реальным объёмом данных. На пустой базе всё летает, и узкое место не проявится. Ещё точнее — снять замер дважды: на «холодной» базе после перезапуска и на «прогретой», когда кэш СУБД уже заполнен, и сравнить.
Как читать логи и находить узкие места
Логи ТЖ — это текстовые файлы, где каждая строка начинается со времени и длительности события. Руками их листать тяжело, поэтому для разбора берут один из подходов:
- 🔎 Поиск по тексту — для разовой проверки. Grep по каталогу логов на
DBMSSQLдаёт список тяжёлых запросов с их текстом и планом. - 📊 Разбор скриптом или утилитой — группировка одинаковых запросов, подсчёт суммарного времени. Повторяющийся средний запрос часто вредит больше, чем единичный тяжёлый.
В событии DBMSSQL обращайте внимание на поля:
Sql— текст запроса к СУБД (не на языке 1С, а уже переведённый).Duration— длительность; именно по ней отбирают кандидатов на оптимизацию.Context— из какого места конфигурации пришёл запрос. Это мостик от SQL обратно к коду.planSQLText(если включён сбор плана) — план выполнения, по нему видно нехватку индексов и сканирование таблиц целиком.
Одна строка лога читается так: сначала идёт время события и его длительность, затем имя события (DBMSSQL), а дальше — пары «свойство=значение». В конце обычно тянется Context с цепочкой вызовов: имя формы, модуля, процедуры. Эта цепочка и есть ответ на вопрос «откуда в коде прилетел тяжёлый запрос» — с неё и начинают правку.
Правило приоритизации простое: сортируйте не по разовой длительности, а по сумме время × число вызовов. Запрос на 0,3 секунды, который дёргается 5000 раз за операцию, съедает больше, чем один на 10 секунд. Поэтому одинаковые по тексту запросы сначала группируют, а потом считают суммарное время по каждой группе — так всплывают «тихие» запросы, которых по отдельности не замечаешь.
Как ловить блокировки и взаимоблокировки
Блокировки — отдельный класс тормозов: запрос сам по себе быстрый, но ждёт, пока данные освободит другой сеанс. В 1С для этого есть управляемые транзакционные блокировки, а в ТЖ — три события.
TLOCK— установка и снятие управляемой блокировки.TTIMEOUT— сеанс не дождался блокировки за отведённое время. По умолчанию таймаут — 20 секунд.TDEADLOCK— взаимоблокировка: два сеанса захватили ресурсы и ждут друг друга. Платформа разрывает одну из транзакций.
Главный приём разбора — найти не жертву, а «держателя». В событии TTIMEOUT есть свойство со списком соединений, из-за которых сеанс не дождался блокировки (в разных релизах оно называется по-своему, смотрите состав свойств события). По номеру соединения из этого списка находят в тех же логах, что именно делал виновник: какой документ проводил, какую длинную транзакцию держал. Без этой связки борьба с блокировками превращается в гадание.
На какие данные встают блокировки, тоже видно: в тексте событий TLOCK и TDEADLOCK указаны пространство блокировок (как правило, это таблица регистра или справочника) и диапазон значений. Если блокируется весь регистр целиком, а не узкий отбор, — это и есть кандидат на оптимизацию управляемых блокировок в коде.
Чаще всего видят такие сообщения:
Режим управления блокировками задан в свойствах конфигурации («Режим управления блокировкой данных»): автоматический, управляемый или смешанный. В современных конфигурациях на платформе 8.3 работают в управляемом режиме — он даёт меньше лишних блокировок, но требует аккуратных блокировок в коде.
Прежде чем советовать «завершить зависший сеанс» — помните, что принудительное завершение оборвёт незаписанную транзакцию пользователя. Сначала найдите причину длинной блокировки в ТЖ, а завершение сеанса держите как крайнюю меру в согласовании с ответственным.
Что делать с найденными медленными запросами
Собрали список тяжёлых запросов и блокировок — дальше оптимизация. Типичные приёмы, от безопасных к радикальным:
- Вынести запрос из цикла. Если код читает базу на каждой итерации — переписать на один запрос, возвращающий всё сразу.
- Добавить отбор и индексы. Запрос без условия по индексированному полю заставляет СУБД читать таблицу целиком. План из ТЖ покажет такие сканирования.
- Не тянуть лишние поля и строки.
ВЫБРАТЬ *по большому регистру — частая причина тормозов; берите только нужные колонки и ограничивайте период. - Пересмотреть временные таблицы и соединения. Соединение с виртуальной таблицей (остатки, обороты) внутри другого запроса нередко лучше заменить предварительным расчётом во временной таблице.
- Сократить транзакции. Чем короче транзакция, тем меньше время удержания блокировок — это лечит и запросы, и конфликты сеансов одновременно.
После каждого изменения снимайте замер заново: оптимизация «на глаз» иногда делает хуже. Сравнивайте цифры до и после на копии с боевым объёмом данных.
Другие инструменты диагностики производительности
ТЖ и замер закрывают большинство случаев, но под разные задачи есть ещё средства.
- 📈 Оценка производительности (APDEX). Встроенная в типовые конфигурации подсистема:
Администрирование → Оценка производительности. Её включают один раз, задают список ключевых операций (проведение реализации, формирование оборотно-сальдовой ведомости и т. п.) и целевое время для каждой. Дальше система сама копит замеры и считает индекс от 0 до 1: чем ближе к единице, тем комфортнее пользователям. Это удобный инструмент для постоянного мониторинга и для предметного разговора «стало быстрее или нет» — вместо спора на ощущениях. - 🛠 Центр управления производительностью (ЦУП). Входит в платный Корпоративный инструментальный пакет (КИП). Визуализирует данные ТЖ и счётчиков, экономит время на ручном разборе логов. Нужен крупным внедрениям.
- 🗄 Средства СУБД. На MS SQL медленные запросы и планы ловят через Extended Events (современная замена SQL Profiler). На PostgreSQL помогают
log_min_duration_statement,auto_explainи расширениеpg_stat_statements. Это уже уровень администратора базы данных.
Для начала хватает связки «замер производительности + технологический журнал». К тяжёлой артиллерии со стороны СУБД переходят, когда штатные средства 1С уже показали виновника, а причину нужно подтвердить планом запроса.
Нужна ли платная лицензия, чтобы диагностировать производительность?
Сильно ли включённый технологический журнал замедляет базу?
Duration: они и диск забивают, и нагрузку добавляют. Собрали данные — выключили.Чем управляемые блокировки отличаются от автоматических?
Где именно смотреть взаимоблокировки?
TDEADLOCK — оно фиксирует обе стороны конфликта и ресурсы, из-за которых сеансы заблокировали друг друга. Журнал регистрации взаимоблокировки не показывает.