Как увидеть и проанализировать план выполнения запроса в 1С
Содержание
Сам язык запросов 1С план выполнения не показывает — его формирует и исполняет СУБД. Поэтому «посмотреть план запроса в 1С» на практике означает одно из двух: получить план средствами платформы через технологический журнал (свойство planSQLText) либо перехватить сгенерированный SQL и построить план уже на стороне сервера баз данных — в SSMS для Microsoft SQL Server или командой EXPLAIN в PostgreSQL.
Быстрый путь для клиент-серверной базы: включить технологический журнал с событием DBMSSQL и фильтром по длительности, в вывод добавить план и текст SQL. Через минуту в логах будут тяжёлые запросы вместе с планом их выполнения. Для разового замера своего запроса удобнее Консоль запросов — она покажет время и структуру, но не сам план.
Важная оговорка: полноценный план доступен только в клиент-серверном варианте (MS SQL или PostgreSQL). В файловой базе внешней СУБД нет, план в привычном виде не снять — там ограничиваются замером времени, а для глубокого разбора временно разворачивают копию базы в клиент-серверном режиме.
Что такое план запроса и где его искать
План запроса (план выполнения) — это последовательность операций, которую СУБД выбирает для получения результата: в каком порядке читаются таблицы, используется поиск по индексу или полное сканирование, как выполняются соединения и сортировки. Именно план объясняет, почему один запрос отрабатывает за миллисекунды, а другой — за минуты на тех же данных.
1С транслирует запрос со своего языка в SQL конкретной СУБД. Дальше оптимизатор СУБД строит план. Значит, искать план нужно там, где он рождается:
- 🧩 на уровне платформы — технологический журнал умеет отдавать план вместе с текстом SQL;
- 🗄️ на уровне СУБД — SSMS (MS SQL) или
EXPLAIN(PostgreSQL) по перехваченному тексту запроса; - ⏱️ на уровне кода — Консоль запросов для замера времени и проверки структуры временных таблиц.
Эти способы не исключают друг друга. Технологический журнал показывает, какие запросы тяжёлые на реальной нагрузке; SSMS и EXPLAIN дают детальный графический разбор одного запроса; консоль помогает быстро проверить гипотезу при переписывании текста.
Консоль запросов: замер времени своего запроса
Консоль запросов — это внешняя обработка (.epf), которую подключают через Файл → Открыть. Она исполняет запрос на языке 1С и показывает результат, длительность и список временных таблиц пакета. Это не просмотр плана СУБД, а инструмент для измерения и отладки текста.
Что даёт консоль при анализе производительности:
- Время выполнения — видно, какой из пакета запросов самый долгий.
- Структуру пакета — все временные таблицы
ПОМЕСТИТЬ, их поля и порядок. - Автозаполнение параметров — удобно подставлять реальные значения периода, организации, отбора.
Пользуйтесь консолью так: выполните запрос, зафиксируйте время, перепишите проблемный фрагмент (например, уберите подзапрос в соединении), выполните снова и сравните. Стабильную разницу видно уже по длительности, даже без просмотра плана.
Для честного замера очищайте кэш СУБД между прогонами или замеряйте «тёплый» запрос несколько раз. Первый прогон после простоя всегда медленнее — данные ещё не в буферах.
Ограничение консоли: она не покажет, что внутри запрос ушёл в полное сканирование таблицы. Для этого всё равно нужен план с уровня СУБД.
Технологический журнал: план прямо из платформы
Это основной штатный способ получить план, не выходя за пределы 1С. Технологический журнал настраивается файлом logcfg.xml, который кладут в каталог conf платформы (например, C:\Program Files\1cv8\conf\logcfg.xml). Платформа подхватывает изменения в течение примерно минуты, перезапуск не нужен.
Минимальная конфигурация для сбора тяжёлых SQL-запросов вместе с планом:
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\v8log" history="4">
<event>
<eq property="name" value="DBMSSQL"/>
<ge property="duration" value="1000000"/>
</event>
<property name="all"/>
</log>
</config>
Разберём ключевое:
- 📁
location— каталог для логов. Создайте его заранее и дайте права на запись пользователю, под которым работает сервер 1С. - 🧭
event name="DBMSSQL"— событие обращения к СУБД. Именно оно несёт текст SQL и план. - ⏳
ge property="duration"— нижний порог длительности. Значение в микросекундах,1000000— это 1 секунда. Так в журнал попадут только долгие запросы, а не весь поток. - 🧾
property name="all"— выгрузить все свойства события, включаяSql,planSQLText,Context,Rows.
В собранных файлах найдите событие DBMSSQL: свойство Sql содержит текст запроса к СУБД, а planSQLText — сам план выполнения. Поле Context показывает, откуда в конфигурации вызван запрос, — это помогает найти проблемный отчёт или проведение документа.
Сбор плана добавляет нагрузку: платформа запрашивает план у СУБД на каждое отловленное событие. Включайте технологический журнал с planSQLText только на время расследования и с фильтром по длительности, а после — сразу выключайте. На продуктивной базе без фильтра журнал быстро забьёт диск и замедлит работу.
Как прочитать графический план в SSMS и PostgreSQL
Когда текст тяжёлого запроса известен (из журнала или профилировщика), детальный разбор удобнее делать на стороне СУБД — там план рисуется графически.
Microsoft SQL Server. Откройте запрос в SQL Server Management Studio. Есть два режима:
Display Estimated Execution Plan(Ctrl+L) — оценочный план без выполнения запроса.Include Actual Execution Plan(Ctrl+M) — фактический план, строится после реального выполнения и показывает настоящее число строк.
Фактический план точнее: по нему видно расхождение оценки и реальности (толстые стрелки на схеме — много строк). Читают план справа налево и сверху вниз.
PostgreSQL. План строит команда EXPLAIN, а с реальными цифрами — EXPLAIN (ANALYZE, BUFFERS):
EXPLAIN (ANALYZE, BUFFERS)
SELECT ... FROM ...;
На что смотреть в любом плане:
| Что видно в плане | Хорошо | Плохо |
|---|---|---|
| Доступ к таблице | Index Seek / Index Scan по нужному индексу | полное сканирование (Table Scan / Seq Scan) большой таблицы |
| Соединения | подходящий тип по объёму данных | Nested Loops на больших наборах |
| Оценка строк | близка к фактической | оценка в разы расходится с фактом |
| Сортировки | по индексу | отдельная тяжёлая сортировка в памяти или на диске |
Для PostgreSQL удобно вставлять вывод EXPLAIN в бесплатные веб-визуализаторы планов — они раскрашивают узлы и подсвечивают самые дорогие операции. Это нагляднее, чем читать текст вручную.
Главный маркер проблемы одинаков для обеих СУБД: полное сканирование большой таблицы вместо поиска по индексу и резкое расхождение оценочного и фактического числа строк.
Профилировщик СУБД: ловим тяжёлые запросы
Если неизвестно даже, какой именно запрос тормозит, нужен профилировщик на стороне сервера баз данных — он пишет поток запросов с длительностью и числом чтений.
- 🔍 SQL Server Profiler — классический инструмент, идёт в комплекте SSMS. Трассировка по событиям и длительности помогает выбрать самые дорогие запросы. На нагруженной базе сама трассировка заметно грузит сервер.
- ⚙️ Extended Events — современная замена Profiler в MS SQL, легче по накладным расходам. На продуктивных серверах предпочтительнее.
- 📊 Центр управления производительностью (ЦУП) из состава инструментов 1С — анализирует технологический журнал и сводит тяжёлые запросы с привязкой к контексту конфигурации. Полезен, когда надо связать нагрузку СУБД с конкретными действиями пользователей.
Схема работы одна: профилировщик отбирает кандидатов по длительности и чтениям, а дальше по найденному тексту строится детальный план в SSMS или через EXPLAIN. Профилировщик отвечает на вопрос «что тормозит», план — на вопрос «почему».
Трассировка профилировщиком и расширенный технологический журнал — нагрузочные операции. На боевом сервере запускайте их адресно, по возможности в часы меньшей активности, и останавливайте сразу после сбора данных.
Временные таблицы и их влияние на план
Временные таблицы — главный рычаг, которым разработчик 1С управляет планом, не трогая настройки СУБД. Оператор ПОМЕСТИТЬ ВременнаяТаблица материализует промежуточный результат: СУБД сохраняет его и дальше работает с фактическими данными, а не с догадками оптимизатора о подзапросе.
Что это меняет в плане:
- ✅ Сложный запрос разбивается на понятные шаги — каждый оптимизируется отдельно.
- ✅ Исчезают дорогие повторные вычисления одного и того же подзапроса.
- ✅ Оптимизатор видит реальный объём промежуточных данных и выбирает соединение точнее.
Ключевой приём — индексировать временную таблицу по полям, по которым она дальше соединяется или фильтруется:
ВЫБРАТЬ
Товар,
Склад
ПОМЕСТИТЬ втОстатки
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Период) КАК Остатки
ИНДЕКСИРОВАТЬ ПО
Товар
Без ИНДЕКСИРОВАТЬ ПО соединение с большой временной таблицей снова уйдёт в сканирование — в плане это будет видно сразу. С индексом СУБД переходит на поиск.
Проверить эффект просто: снимите план до и после переписывания запроса на временные таблицы. Если полное сканирование сменилось поиском по индексу, а длительность упала — приём сработал.
Типичные узкие места, которые выдаёт план
Разбирая план, вы почти всегда встретите один из знакомых паттернов. Вот что чаще всего видно в проблемных запросах 1С:
- 🐌 Полное сканирование большой таблицы. Нет подходящего индекса либо условие написано так, что индекс не применяется.
- 🔗 Соединение с вложенным запросом. Подзапрос в
СОЕДИНЕНИЕоптимизатор нередко выполняет построчно — отсюда долгие вложенные циклы. - 🧮 Функции над полем в условии. Обёртка поля в выражение (
ПОДСТРОКА, приведение типа, арифметика) мешает использовать индекс. - 🔀 Условие через
ИЛИиВ (ВЫБРАТЬ …). Такие конструкции часто рушат поиск по индексу. - 📦 Отбор снаружи виртуальной таблицы. Когда фильтр по организации или складу стоит в общем
ГДЕ, а не в параметрах виртуальной таблицы остатков. - 🧊 Устаревшая статистика СУБД. Оптимизатор строит план по неактуальным данным и ошибается в оценке строк — в фактическом плане оценка резко расходится с реальностью.
Каждый из этих паттернов читается в плане как лишняя дорогая операция: толстая стрелка, полное сканирование, оценка строк, далёкая от факта.
Практические приёмы оптимизации по плану
Когда узкое место найдено, работают проверенные приёмы. Применяйте их адресно — по тому, что показал план, а не все сразу.
- Переносите отбор в параметры виртуальных таблиц. Пишите
Остатки(&Период, Организация = &Организация)вместо фильтра вГДЕ. Виртуальная таблица отберёт меньше данных на входе. - Разбивайте запрос на временные таблицы и индексируйте их по полям соединения — это чаще всего и меняет план к лучшему.
- Убирайте подзапросы из соединений. Сначала соберите данные во временную таблицу, затем соединяйте с ней.
- Не оборачивайте индексируемые поля функциями в условиях — иначе индекс не используется.
- Задавайте явные типы через
ВЫРАЗИТЬ(… КАК …)для полей составного типа — это убирает лишние соединения по всем таблицам типа. - Обновляйте статистику и обслуживайте индексы на СУБД регламентными заданиями: без свежей статистики даже правильный запрос получит плохой план.
После каждого изменения снимайте план заново. Оптимизация запроса — это цикл «снял план → увидел проблему → переписал → снял план снова», а не разовая правка вслепую.
Прежде чем менять индексы или настройки обслуживания на продуктивной СУБД, согласуйте изменения с администратором баз данных. Неудачный индекс ускорит чтение, но замедлит запись и проведение документов.
Частые вопросы
Можно ли посмотреть план запроса без доступа к СУБД?
planSQLText: план придёт от платформы, прямой доступ к серверу баз данных не нужен. Но для детального графического разбора в SSMS или через EXPLAIN доступ к СУБД понадобится.Как снять план для файловой базы?
Чем оценочный план отличается от фактического?
Почему один и тот же запрос то быстрый, то медленный?
Технологический журнал не замедлит рабочую базу?
planSQLText. Ставьте порог по длительности, собирайте только событие DBMSSQL и выключайте журнал сразу после расследования.