Когда пользователь говорит, что «1С тормозит», это еще не техническая постановка задачи. Для начала нужно определить, на каком именно участке тратится время.
Если проблема связана с обращением к СУБД, одна из первых задач — получить конкретные длительные запросы и ответить на два вопроса:
- какой SQL выполнялся;
- из какого места конфигурации он был вызван.
Для этого не требуется устанавливать отдельную систему мониторинга. Все необходимые для такой первичной диагностики данные умеет собирать сама платформа — в технологический журнал.
Сразу определимся с терминологией. В этой статье под длительным запросом я буду понимать запрос, выполнение которого превысило выбранный нами порог времени. В рабочем примере ниже этот порог — 30 секунд.
Попадание запроса в выборку «дольше 30 секунд» еще не означает, что текст запроса написан неправильно. Длительность конкретного обращения к СУБД фиксирует сам факт: операция DBMSSQL заняла больше установленного порога. Причина такой длительности устанавливается отдельно — по плану выполнения, статистике чтений, ожиданиям, блокировкам и другим данным СУБД.
Здесь мы решаем другую задачу: надежно найти такие запросы и локализовать их в конфигурации.
Сторонние системы мониторинга автоматизируют эту работу: собирают технологический журнал, разбирают события, группируют запросы, сохраняют статистику, связывают SQL с контекстом вызова. Это удобно, особенно при постоянном мониторинге нескольких серверов.
Но исходную информацию для поиска длительных запросов можно получить непосредственно из технологического журнала. Именно этот способ я и хочу разобрать — полезно хотя бы один раз пройти весь путь вручную и понимать, откуда берутся данные, которые показывают специализированные инструменты.
В статье рассматривается клиент-серверная 1С:Предприятие 8.3 с Microsoft SQL Server.
Настраиваем технологический журнал
Нас интересует событие DBMSSQL.
Это событие регистрирует выполнение платформой SQL-оператора в Microsoft SQL Server. Для PostgreSQL используется событие DBPOSTGRS, для Oracle — DBORACLE. Методика поиска остается той же, но имя события выбирается в соответствии с используемой СУБД.
Нам нужны не все SQL-запросы. На рабочей базе их количество велико, поэтому запись каждого события создаст ненужный объем журнала. В этом примере отбираем обращения к MS SQL Server длительностью строго больше 30 секунд.
Для этого достаточно следующего logcfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="F:\1c_logs\queries" history="8">
<event>
<eq property="Name" value="DBMSSQL"/>
<eq property="p:processName" value="erp_prod"/>
<gt property="Durationus" value="30000000"/>
</event>
<property name="all"/>
</log>
</config>
В Windows 64-bit при стандартной установке общий каталог конфигурационных файлов платформы — C:\Program Files\1cv8\conf (для 64-bit версии платформы). Если разместить logcfg.xml здесь, одна настройка применяется ко всем установленным версиям платформы, которые используют стандартный общий каталог конфигурации. На сервере из примера logcfg.xml расположен именно в этом каталоге. Если в conf.cfg конкретной версии задан другой ConfLocation, фактический каталог конфигурационных файлов определяется этим параметром. Если кластер включает несколько рабочих серверов, logcfg.xml нужно разместить на каждом сервере, где могут выполняться процессы rphost исследуемой информационной базы.

Рисунок 1. Файл logcfg.xml в общем каталоге конфигурационных файлов C:\Program Files\1cv8\conf.
Разберем настройку по строкам.
location
<log location="F:\1c_logs\queries" history="8">
location задает каталог, в который будут записываться файлы технологического журнала. Процессы 1С, формирующие журнал, должны иметь права записи в этот каталог. Под журнал лучше выделить отдельный каталог на диске с достаточным запасом свободного места и не использовать системный диск: даже с фильтром объем журнала на нагруженной базе может оказаться неожиданно большим.
history="8" задает срок хранения файлов журнала — 8 часов. После истечения указанного периода платформа удаляет устаревшие файлы.
В этом примере установлен срок хранения 8 часов. Такой интервал ограничивает объем технологического журнала при разовой диагностике. Если сбор должен охватывать более длительный период, значение history нужно увеличить заранее.
Name="DBMSSQL"
<eq property="Name" value="DBMSSQL"/>
Мы отбираем только события DBMSSQL, то есть SQL-операторы, отправляемые платформой в Microsoft SQL Server.
Важно различать DBMSSQL и SDBL. SDBL описывает обращение платформы к внутренней модели базы данных 1С. DBMSSQL относится уже к SQL, который выполняется на MS SQL Server.
Если задача звучит как «покажи мне SQL, который выполнялся на сервере СУБД», основным интересующим нас событием является DBMSSQL.
p:processName
<eq property="p:processName" value="erp_prod"/>
В выбранном технологическом журнале события исследуемой базы имеют p:processName=erp_prod, поэтому в фильтре используется именно это значение. В тех же событиях свойство DataBase равно sql-srv\erp_prod. Для отбора по этой базе нам достаточно фактического значения p:processName из журнала; имя базы на стороне СУБД задается отдельным свойством DataBase.
Такой отбор особенно важен на сервере, где один кластер обслуживает несколько информационных баз: без него в журнал попадут SQL-события не только исследуемой базы.
Durationus
<gt property="Durationus" value="30000000"/>
Durationus — длительность события в микросекундах.
1 секунда = 1 000 000 мкс
30 секунд = 30 000 000 мкс
Условие выше означает: регистрировать события длительностью строго больше 30 секунд. Оператор gt означает greater than — «больше». Если нужно включать события ровно с 30 секунд, используется ge — greater or equal.
В старых примерах настройки технологического журнала часто встречается вариант:
<gt property="Duration" value="300000"/>
Свойство Duration измеряет длительность в сотнях микросекунд: 300 000 × 100 мкс = 30 000 000 мкс = 30 секунд.
Начиная с версии 8.3.3 платформа выводит время событий технологического журнала с дискретностью 1 микросекунда и поддерживает свойство Durationus, содержащее длительность события в микросекундах. Свойство Duration сохранено для совместимости; его значение выражается в сотнях микросекунд. Для новых настроек 1С рекомендует использовать Durationus.
Важно: Duration и Durationus имеют разные единицы измерения. В одном файле настройки их нельзя интерпретировать одинаково.
property name="all"
<property name="all"/>
Эта строка говорит платформе выводить доступные свойства выбранных событий. Она не включает все события технологического журнала.
Какие события попадут в файл, определено блоком <event>. В нашем случае это только DBMSSQL для серверного контекста erp_prod с длительностью строго больше 30 секунд.
property name="all" нужен потому, что кроме самого SQL нам необходимы SessionID, пользователь, приложение, количество строк и, самое главное, Context.
А где <plansql/>?
В примерах настройки на ИТС можно встретить дополнительный элемент — сбор планов запросов:
<plansql/>
В полном файле этот элемент располагается на уровне config:
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="F:\1c_logs\queries" history="8">
<event>
<eq property="Name" value="DBMSSQL"/>
<eq property="p:processName" value="erp_prod"/>
<gt property="Durationus" value="30000000"/>
</event>
<property name="all"/>
</log>
<plansql/>
</config>
Этот элемент включает получение планов запросов. Сбор планов создает дополнительную нагрузку, поэтому для задачи этой статьи он не нужен: сначала достаточно собрать DBMSSQL, найти длительный запрос и его Context. Если затем требуется анализировать причину длительного выполнения, планы лучше собирать отдельным коротким замером с максимально узким фильтром.
Когда начнется запись?
Платформа периодически перечитывает logcfg.xml. После изменения файла нужно дождаться применения новой настройки рабочими процессами; в практической работе для этого обычно достаточно около минуты.
После этого выполняем интересующую операцию либо оставляем сбор на необходимый период. Для серверной информационной базы интерес представляют прежде всего файлы, сформированные рабочими процессами rphost.
Где лежат файлы и как отобрать самые долгие события?
При стандартном размещении файлов технологического журнала внутри каталога location создаются подкаталоги по процессам, например rphost_4812, где 4812 — идентификатор процесса. В каждом таком каталоге журнал разбит на часовые файлы с именами вида ГГММДДЧЧ.log: файл 26091617.log содержит события за 16.09.2026 с 17:00 до 18:00. В самой записи указаны минуты, секунды и микросекунды, а дата и час определяются по имени файла. Если явно используется режим placement="plain", структура размещения файлов будет другой; в конфигурации из этой статьи этот режим не задан.

Рисунок 2. Часовые файлы технологического журнала. Имя файла имеет формат ГГММДДЧЧ; расширение .log на снимке скрыто настройками Проводника.
Для первичного отбора не нужны специальные инструменты. Скрипт PowerShell ниже проходит по всем файлам журнала, выделяет события DBMSSQL и сохраняет в текстовый файл 20 самых долгих из них вместе с SQL и Context:
# Каталог из параметра location в logcfg.xml
$root = 'F:\1c_logs\queries'
$top = 20
$report = 'F:\1c_logs\top_dbmssql.txt'
# Новое событие начинается со строки вида "мм:сс.микросекунды-длительность,"
$eventStart = '(?m)^(?=\d{2}:\d{2}\.\d{6}-\d+,)'
$header = '^(\d{2}:\d{2}\.\d{6})-(\d+),DBMSSQL,'
Get-ChildItem -Path $root -Recurse -Filter *.log | ForEach-Object {
$file = $_
$text = [System.IO.File]::ReadAllText($file.FullName, [System.Text.Encoding]::UTF8)
foreach ($ev in ($text -split $eventStart)) {
if ($ev -match $header) {
[pscustomobject]@{
# Дата и час — из имени файла ГГММДДЧЧ.log
Time = '{0} {1}' -f $file.BaseName, $Matches[1]
Seconds = [math]::Round([int64]$Matches[2] / 1000000, 3)
Process = $file.Directory.Name
Event = $ev.Trim()
}
}
}
} | Sort-Object Seconds -Descending | Select-Object -First $top |
Format-List Time, Seconds, Process, Event |
Out-File -FilePath $report -Width 4096 -Encoding utf8
Скрипт сохраните в кодировке UTF-8 с BOM, иначе Windows PowerShell 5.1 неправильно прочитает кириллицу в пути. Файлы журнала он читает целиком, поэтому рассчитан на журнал, уже ограниченный фильтром, а не на многогигабайтный сбор всех событий.
Разбираем событие технологического журнала
Разберем реальное событие DBMSSQL из рабочего журнала — оно найдено в файле 26091617.log. Имена сервера приложений, сервера СУБД и информационной базы обезличены; длительность события, структура SQL и цепочка Context сохранены.
16:35.424006-88202877,DBMSSQL,5,level=DEBUG,process=rphost,
p:processName=erp_prod,OSThread=4088,t:clientID=77342,
t:applicationName=BackgroundJob,t:computerName=APP-SRV,
t:connectID=73134,SessionID=27250,Usr=DefUser,
DBMS=DBMSSQL,DataBase=sql-srv\erp_prod,Trans=1,dbpid=104,
Sql='SELECT
T2.Fld19589_,
T1._Fld23013_TYPE,
T1._Fld23013_RTRef,
T1._Fld23013_RRRef,
T1._Fld23480,
CASE
WHEN T1._Fld23013_TYPE = 0x08
AND T1._Fld23013_RTRef = 0x00000149 THEN T6._Fld9311
WHEN T1._Fld23013_TYPE = 0x08
AND T1._Fld23013_RTRef = 0x00000141 THEN T7._Fld8823
ELSE CAST(NULL AS NUMERIC(15, 2))
END,
MAX(T2.Period_)
FROM dbo._InfoRg23011 T1
LEFT OUTER JOIN (...) T2 ON (...)
LEFT OUTER JOIN dbo._Document329 T6 ON (...)
LEFT OUTER JOIN dbo._Document321 T7 ON (...)
WHERE ...
GROUP BY ...
p_0: 0N
p_1: 40260916170459
...
p_8: 0x00000000000000000000000000000003
',Rows=0,RowsAffected=0,Context='
...
ОбщийМодуль.ИнтеграцияСЛогистикой.Модуль : 14786 :
ВнешняяОбработка.ВыполнитьПроверки(...);
ВнешняяОбработка.ПроверкаЗаказов.МодульОбъекта : 90 :
ПроверитьСуммыПредоплаченныхЗаказов(стрЗаписей, Ложь);
ВнешняяОбработка.ПроверкаЗаказов.МодульОбъекта : 162 :
РезультатЗапроса = Запрос.Выполнить();'
В публикации SQL в этом листинге сокращен многоточиями: удалена часть списка полей, вложенного подзапроса и условий, которые не нужны для разбора структуры события. Заголовок DBMSSQL, длительность, ключевые свойства, Rows/RowsAffected и финальные строки Context сохранены. В одной записи уже есть все данные, необходимые на этом этапе: длительность обращения к СУБД, физический SQL и Context, ведущий к прикладному коду 1С.
В заголовке события зафиксированы process=rphost, p:processName=erp_prod, t:applicationName=BackgroundJob, SessionID=27250, Usr=DefUser, DBMS=DBMSSQL, Trans=1, DataBase=sql-srv\erp_prod и dbpid=104. Далее в свойстве Sql расположен выполненный оператор SQL, а после него — Rows, RowsAffected и Context.
Длительность события
16:35.424006-88202877,DBMSSQL,5
Число 88202877 после дефиса — длительность события в микросекундах. 88 202 877 мкс = 88,202877 секунды.
process=rphost
process=rphost
Событие сформировано рабочим процессом сервера 1С. Для серверного выполнения запросов это ожидаемый процесс.
t:applicationName
t:applicationName=BackgroundJob
Значение BackgroundJob означает, что событие относится к фоновому заданию.
Это сразу дает полезный первый разрез: запрос пришел из интерактивной работы пользователя или из фоновой серверной операции.
SessionID
SessionID=27250
SessionID — идентификатор сеанса 1С. По нему удобно связывать события, принадлежащие одному сеансу, особенно если анализируется не одна строка, а цепочка событий.
Usr
Usr=DefUser
Usr=DefUser — пользователь информационной базы, в контексте которого выполнялось это фоновое задание.
Trans
Trans=1
Trans=1 означает, что обращение к СУБД выполнялось в рамках транзакции. Само значение Trans=1 не показывает наличие ожиданий и не определяет, какие блокировки были установлены или как долго они удерживались. Если требуется проверить влияние блокировок на длительность запроса, это устанавливается отдельно по данным о блокировках и ожиданиях СУБД.
DBMS
DBMS=DBMSSQL
Свойство DBMS в данном событии указывает используемую СУБД — Microsoft SQL Server. Имя самого события также DBMSSQL и записано непосредственно после длительности в начале строки.
Rows
Rows=0,RowsAffected=0
Rows=0 означает, что оператор не вернул строк результата. RowsAffected=0 в данном SELECT не характеризует объем чтения и не объясняет длительность выполнения. Эти значения не отменяют зафиксированный факт: обращение к MS SQL Server заняло 88,202877 секунды.
Количество возвращенных строк нельзя использовать как меру объема работы СУБД. Запрос может вернуть ноль строк после чтения и обработки большого объема данных. Объем чтений и конкретные операции определяются по плану выполнения и статистике СУБД.
Context — как найти запрос в конфигурации
В выбранном DBMSSQL поле Context находится в той же записи, сразу после Rows и RowsAffected. Полностью оно приведено в событии выше, здесь — последние строки стека:
Context='
...
ОбщийМодуль.ИнтеграцияСЛогистикой.Модуль : 14786 : ВнешняяОбработка.ВыполнитьПроверки(...);
ВнешняяОбработка.ПроверкаЗаказов.МодульОбъекта : 90 : ПроверитьСуммыПредоплаченныхЗаказов(стрЗаписей, Ложь);
ВнешняяОбработка.ПроверкаЗаказов.МодульОбъекта : 162 : РезультатЗапроса = Запрос.Выполнить();'
Context — контекст исполнения события. В данном случае он показывает цепочку вызовов, которая непосредственно привела к выполнению этого SQL.
В выбранном событии строки Context идут от внешнего вызова к более глубоким вызовам; последняя строка показывает место, где непосредственно выполнялся Запрос.Выполнить(). Поэтому этот Context удобно разбирать снизу вверх: от непосредственного обращения к базе к процедурам, которые к нему привели.
Context присутствует не у каждого события технологического журнала. Если его нет, для корреляции используют идентификаторы сеанса и соединения (в частности SessionID и t:connectID), время события и другие события того же выполнения. Само соседство строк в файле не доказывает, что события относятся к одной прикладной операции.
Строки Context содержат объект или модуль конфигурации, номер строки и исполняемое выражение. Благодаря этому SQL из технологического журнала можно связать с конкретным местом прикладного кода.
<объект или модуль> : <номер строки> : <фрагмент выполняемого кода>
Например:
ВнешняяОбработка.ПроверкаЗаказов.МодульОбъекта : 162 :
РезультатЗапроса = Запрос.Выполнить();
Эта строка локализует вызов точно: внешняя обработка ПроверкаЗаказов, модуль объекта, строка 162. В этой строке выполняется метод Запрос.Выполнить(), то есть найден непосредственный вызов запроса, породившего рассматриваемое событие DBMSSQL.
SQL Server оперирует физическими таблицами и полями 1С — в этом запросе, например, dbo._InfoRg23011, dbo._InfoRg19587, dbo._Document329 и dbo._Document321. Context возвращает нас из физического слоя СУБД в конкретный прикладной код 1С.
Почему Context бывает многострочным
Context — не одно свойство вида «имя процедуры». Он содержит цепочку вложенных вызовов.
В нашем примере цепочка начинается в механизме дополнительных отчетов и обработок, проходит через внешнюю обработку ВыгрузкаЗаказовДоставки и общий модуль ИнтеграцияСЛогистикой, затем приходит во внешнюю обработку ПроверкаЗаказов к строке 162, где выполняется Запрос.Выполнить().
Поэтому событие технологического журнала физически занимает несколько строк. Это важно учитывать, если журнал разбирается собственным скриптом: нельзя считать каждую текстовую строку отдельным событием. И SQL, и Context способны быть многострочными. Признак начала нового события — строка, которая начинается с метки времени вида мм:сс.микросекунды-длительность.
Для ручного анализа это, наоборот, удобно — перед нами фактически готовая трасса исполнения.
Получаем SQL в терминах метаданных 1С
Итак, у нас есть SQL из DBMSSQL. Проблема в том, что выглядит он примерно так:
FROM dbo._InfoRg23011 T1
LEFT OUTER JOIN (...) T2
ON (T1._Fld23013_TYPE = T2.Fld19588_TYPE
AND T1._Fld23013_RTRef = T2.Fld19588_RTRef
AND T1._Fld23013_RRRef = T2.Fld19588_RRRef)
LEFT OUTER JOIN dbo._Document329 T6
ON (T1._Fld23013_TYPE = 0x08
AND T1._Fld23013_RTRef = 0x00000149
AND T1._Fld23013_RRRef = T6._IDRRef)
LEFT OUTER JOIN dbo._Document321 T7
ON (T1._Fld23013_TYPE = 0x08
AND T1._Fld23013_RTRef = 0x00000141
AND T1._Fld23013_RRRef = T7._IDRRef)
Для SQL Server это нормальные физические имена таблиц. Для разработчика конфигурации они малоинформативны.
Вместо физических имен _InfoRg23011, _InfoRg19587, _Document329, _Document321 и _Fld... разработчику нужны соответствующие им регистры, документы и поля конфигурации. Для этого используется структура хранения базы данных или специализированный конвертер.
Здесь есть два рабочих варианта.
Вариант 1. Получить структуру хранения средствами платформы
У платформы существует функция:
ПолучитьСтруктуруХраненияБазыДанных()
Она возвращает информацию о соответствии объектов конфигурации их физическим таблицам и полям базы данных. Эта информация используется в том числе для анализа записей технологического журнала.
Например:
СтруктураБазыДанных = ПолучитьСтруктуруХраненияБазыДанных(, Истина);
После этого можно определить, какому объекту метаданных соответствует таблица из секции FROM, а затем расшифровать физические поля. Второй параметр ИменаБазыДанных = Истина здесь важен: с ним функция возвращает имена таблиц и полей в терминах СУБД — в том же виде, в каком они встречаются в SQL из DBMSSQL, например _Fld23013_RRRef.
Для постоянной работы удобнее использовать готовую обработку просмотра структуры БД: вручную искать соответствия по таблице значений неудобно.
Вариант 2. Автоматически преобразовать физические имена
Есть специализированные обработки, которые получают SQL и автоматически заменяют физические имена таблиц и полей их представлениями в терминах метаданных.
Например: Конвертер SQL и планов запросов в представления языка 1С на Инфостарт
Здесь важно точно понимать результат такого преобразования. Оно не восстанавливает исходный текст запроса 1С один в один: платформа уже выполнила трансляцию исходного запроса, добавила необходимые конструкции и сформировала SQL для конкретной СУБД.
Обработка заменяет физические представления таблиц и полей на соответствующие им объекты и реквизиты метаданных. В простых случаях результат получается близким к привычному языку запросов 1С, в сложных случаях требуется ручной анализ.
Ищем исходный запрос в конфигураторе
На этом этапе у нас есть две независимые зацепки.
Первая — Context. Например:
ВнешняяОбработка.ПроверкаЗаказов.МодульОбъекта : 162
Вторая — объекты метаданных, к которым обращается SQL.
В простом случае этого достаточно, чтобы быстро найти исходный запрос.
Если Context приводит непосредственно в процедуру, содержащую:
Запрос = Новый Запрос;
Запрос.Текст = ...
задача локализации закончена.
В нашем примере Context приводит непосредственно к строке:
ВнешняяОбработка.ПроверкаЗаказов.МодульОбъекта : 162 :
РезультатЗапроса = Запрос.Выполнить();
Здесь локализация однозначна: открываем модуль объекта внешней обработки ПроверкаЗаказов и переходим к строке 162. Непосредственно в этой строке выполняется объект Запрос.
Важная деталь: это внешняя обработка, и номер строки 162 относится к той ее версии, которая фактически выполнялась. Если обработка подключена через «Дополнительные отчеты и обработки», ее нужно выгрузить из этого справочника; если прикладной код создает ее из файла или макета — взять из того же источника. Локальная копия может отличаться, и строка 162 окажется совсем другой. Для кода конфигурации правило то же: номера строк соответствуют конфигурации базы данных с учетом расширений, а не основной конфигурации, уже измененной в конфигураторе.
Дальше в этой же процедуре нужно найти формирование текста Запрос.Текст и установку параметров запроса. Физический SQL из DBMSSQL используется для проверки соответствия найденного участка кода реальному обращению к СУБД.
В других случаях Context может привести не к явному Запрос.Выполнить(), а к СКД, динамическому списку или другому механизму платформы, который формирует SQL автоматически. Тогда дальнейший поиск выполняется уже внутри соответствующего механизма.
Правильная цепочка поиска: SQL → Context → объект конфигурации → конкретный механизм формирования запроса.
Глобальный текстовый поиск SQL по конфигурации в общем случае не работает, поскольку SQL Server получает уже преобразованный платформой запрос с физическими именами таблиц и полей.
Что именно мы получили в результате
После всей процедуры у нас уже не абстрактная жалоба «система тормозит» и не просто факт «есть долгий запрос».
У нас появляется полноценная постановка задачи для оптимизации:
В рассматриваемом случае зафиксировано событие DBMSSQL длительностью 88,202877 секунды в базе erp_prod. Запрос выполнялся фоновым заданием в рамках транзакции (Trans=1), SessionID=27250, Usr=DefUser. Context приводит к ВнешняяОбработка.ПроверкаЗаказов.МодульОбъекта, строка 162, где выполняется РезультатЗапроса = Запрос.Выполнить(). То есть одновременно известны фактический SQL, длительность обращения к MS SQL Server и точное место выполнения запроса в прикладном коде.
Вот с этой точки уже начинается оптимизация. И это отдельная задача.
Поиск медленного запроса и его оптимизация — разные этапы
После обнаружения длительного запроса причины его выполнения могут быть разными. Дальше уже необходимо смотреть:
- фактический или расчетный план выполнения;
- объем чтений;
- операции Scan и Seek;
- соединения таблиц;
- оценки количества строк;
- индексы;
- параметры запроса;
- разыменование составных типов;
- виртуальные таблицы регистров;
- временные таблицы;
- условия соединения;
- RLS;
- количество возвращаемых и обрабатываемых строк;
- влияние ожиданий и блокировок.
Попытка дать универсальный совет «добавьте индекс» сразу после обнаружения запроса — это не оптимизация.
Сначала запрос необходимо найти и точно локализовать. Затем установить причину его стоимости. И только после этого менять запрос, структуру хранения или прикладную логику.
В разобранном SQL видна характерная конструкция, которую платформа формирует при обращении к реквизитам ссылок составного типа: проверки _TYPE и _RTRef и выбор значения через CASE. В данном запросе такая конструкция участвует и в условии отбора. Влияние подобных выражений на план выполнения и способы их устранения — тема отдельной статьи.
Этой статьей закрыт первый этап.
Короткая памятка
- Настраиваем logcfg.xml на событие DBMSSQL для нужной информационной базы.
- Ограничиваем события по Durationus.
- Отбираем из файлов журнала самые долгие события.
- Забираем SQL.
- Смотрим Context.
- По Context определяем объект, модуль и строку конфигурации.
- Через структуру хранения расшифровываем физические имена таблиц SQL.
- Находим механизм, сформировавший запрос.
- После локализации переходим к анализу плана и непосредственно к оптимизации.
Все это можно выполнить без отдельной системы мониторинга.
Специализированные инструменты делают тот же процесс значительно удобнее при регулярной эксплуатации: автоматически собирают, хранят, группируют и визуализируют данные. Но понимание исходного механизма сильно упрощает работу в тех случаях, когда готовый инструмент показывает «медленный запрос», а дальше нужно самостоятельно разобраться, почему он медленный и где именно находится его источник в конфигурации.
Источники и ссылки
- Технологический журнал — 1С:Предприятие
- Методическая поддержка 1С: пример настройки DBMSSQL и plansql
- Методическая поддержка 1С: сбор и анализ планов SQL
- ПолучитьСтруктуруХраненияБазыДанных — пример разработки
- Конвертер SQL и планов запросов в представления языка 1С — Инфостарт
- Изменения платформы 8.3.3: Durationus и совместимость с Duration
- Расположение logcfg.xml и общий каталог конфигурационных файлов — 1С:Предприятие
Вступайте в нашу телеграмм-группу Инфостарт