Как увидеть и проанализировать план выполнения запроса в 1С

· 10 мин

Содержание

Сам язык запросов 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. Время выполнения — видно, какой из пакета запросов самый долгий.
  2. Структуру пакета — все временные таблицы ПОМЕСТИТЬ, их поля и порядок.
  3. Автозаполнение параметров — удобно подставлять реальные значения периода, организации, отбора.

Пользуйтесь консолью так: выполните запрос, зафиксируйте время, перепишите проблемный фрагмент (например, уберите подзапрос в соединении), выполните снова и сравните. Стабильную разницу видно уже по длительности, даже без просмотра плана.

Для честного замера очищайте кэш СУБД между прогонами или замеряйте «тёплый» запрос несколько раз. Первый прогон после простоя всегда медленнее — данные ещё не в буферах.

Ограничение консоли: она не покажет, что внутри запрос ушёл в полное сканирование таблицы. Для этого всё равно нужен план с уровня СУБД.

Технологический журнал: план прямо из платформы

Это основной штатный способ получить план, не выходя за пределы 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 только на время расследования и с фильтром по длительности, а после — сразу выключайте. На продуктивной базе без фильтра журнал быстро забьёт диск и замедлит работу.

Снимаем план через технологический журнал
Выполнено: 0 / 6

Как прочитать графический план в 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С:

  • 🐌 Полное сканирование большой таблицы. Нет подходящего индекса либо условие написано так, что индекс не применяется.
  • 🔗 Соединение с вложенным запросом. Подзапрос в СОЕДИНЕНИЕ оптимизатор нередко выполняет построчно — отсюда долгие вложенные циклы.
  • 🧮 Функции над полем в условии. Обёртка поля в выражение (ПОДСТРОКА, приведение типа, арифметика) мешает использовать индекс.
  • 🔀 Условие через ИЛИ и В (ВЫБРАТЬ …). Такие конструкции часто рушат поиск по индексу.
  • 📦 Отбор снаружи виртуальной таблицы. Когда фильтр по организации или складу стоит в общем ГДЕ, а не в параметрах виртуальной таблицы остатков.
  • 🧊 Устаревшая статистика СУБД. Оптимизатор строит план по неактуальным данным и ошибается в оценке строк — в фактическом плане оценка резко расходится с реальностью.

Каждый из этих паттернов читается в плане как лишняя дорогая операция: толстая стрелка, полное сканирование, оценка строк, далёкая от факта.

Практические приёмы оптимизации по плану

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

  1. Переносите отбор в параметры виртуальных таблиц. Пишите Остатки(&Период, Организация = &Организация) вместо фильтра в ГДЕ. Виртуальная таблица отберёт меньше данных на входе.
  2. Разбивайте запрос на временные таблицы и индексируйте их по полям соединения — это чаще всего и меняет план к лучшему.
  3. Убирайте подзапросы из соединений. Сначала соберите данные во временную таблицу, затем соединяйте с ней.
  4. Не оборачивайте индексируемые поля функциями в условиях — иначе индекс не используется.
  5. Задавайте явные типы через ВЫРАЗИТЬ(… КАК …) для полей составного типа — это убирает лишние соединения по всем таблицам типа.
  6. Обновляйте статистику и обслуживайте индексы на СУБД регламентными заданиями: без свежей статистики даже правильный запрос получит плохой план.

После каждого изменения снимайте план заново. Оптимизация запроса — это цикл «снял план → увидел проблему → переписал → снял план снова», а не разовая правка вслепую.

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

Частые вопросы

Можно ли посмотреть план запроса без доступа к СУБД?
Отчасти да — через технологический журнал со свойством planSQLText: план придёт от платформы, прямой доступ к серверу баз данных не нужен. Но для детального графического разбора в SSMS или через EXPLAIN доступ к СУБД понадобится.
Как снять план для файловой базы?
В привычном виде — никак: внешней СУБД в файловом варианте нет. Ограничьтесь замером времени через Консоль запросов. Для серьёзного анализа разверните копию базы в клиент-серверном режиме и работайте уже с ней.
Чем оценочный план отличается от фактического?
Оценочный строится без выполнения запроса, по статистике, и показывает предполагаемое число строк. Фактический строится после реального выполнения и содержит настоящие цифры. Именно по расхождению оценки и факта находят проблемы с устаревшей статистикой.
Почему один и тот же запрос то быстрый, то медленный?
Чаще всего из-за кэша СУБД (первый прогон холодный), устаревшей статистики или разного объёма данных по параметрам отбора. Снимайте фактический план в тот момент, когда запрос реально тормозит.
Технологический журнал не замедлит рабочую базу?
Замедлит, если собирать всё без фильтра, особенно с planSQLText. Ставьте порог по длительности, собирайте только событие DBMSSQL и выключайте журнал сразу после расследования.