Диагностика запроса 1С: от синтаксиса до плана выполнения

· 9 мин

Содержание

Быстрее всего проверить запрос в 1С так: откройте консоль запросов, вставьте текст, подставьте параметры и нажмите «Выполнить». Результат и ошибка синтаксиса появятся сразу, без изменения кода конфигурации. Если запрос отдаёт верные данные, но работает медленно — включите замер производительности в отладчике и посмотрите реальный SQL.

Проверка запроса распадается на три независимые задачи: синтаксис (текст разбирается без ошибок), логика (данные те, что нужны) и производительность (запрос не висит на боевой базе). Для каждой — свой инструмент. Ниже разберём, чем проверять запрос на каждом уровне, как увидеть план выполнения на стороне СУБД и какие ошибки в тексте встречаются чаще всего.

Какой инструмент выбрать под задачу

Прежде чем лезть в код, определитесь, что именно вы проверяете. От этого зависит инструмент.

Что нужно проверить в запросе?

Дальше — каждый инструмент по порядку, от простого к глубокому.

Проверка в консоли запросов

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

Чтобы её открыть:

  1. Возьмите обработку «Консоль запросов» из комплекта стандартных обработок (она идёт в составе дисков ИТС и типовых поставок).
  2. В 1С:Предприятии зайдите в Файл → Открыть и укажите файл обработки.
  3. В поле текста вставьте запрос, при необходимости задайте параметры на отдельной вкладке.
  4. Нажмите «Выполнить» — результат появится в таблице внизу.

Открытие внешних обработок требует соответствующего права у пользователя. Если пункт Файл → Открыть недоступен, попросите администратора выдать роль с правом на интерактивное открытие внешних обработок — на боевой базе это ограничивают намеренно.

Что консоль показывает:

  • 🔴 ошибку синтаксиса с указанием позиции в тексте — например «Поле не найдено» или «Ожидается выражение»;
  • 📊 таблицу результата — можно сразу сверить цифры с отчётом;
  • ⏱ время выполнения запроса в миллисекундах (в большинстве версий консоли).

Для разовой проверки логики консоли достаточно: подставили параметры периода и организации, выполнили, глазами сравнили итог с оборотно-сальдовой ведомостью.

Многие версии консоли умеют показывать текст запроса на языке СУБД и временные таблицы. Это пригодится, когда дойдёте до разбора производительности.

Отдельно стоит проверять пакетные запросы — те, что собирают несколько временных таблицы через ПОМЕСТИТЬ. В консоли такой пакет выполняется целиком, и после прогона видно содержимое каждой временной таблицы. Это удобный способ поймать ошибку на промежуточном шаге: часто неверные данные появляются не в финальной выборке, а в одной из временных таблиц по дороге.

Проверка синтаксиса через конструктор запроса

Если запрос пишется в коде модуля, синтаксис проще проверять конструктором запроса. Он доступен в конфигураторе и в 1С:EDT.

В конфигураторе поставьте курсор внутрь строки с текстом запроса, нажмите правую кнопку мыши и выберите «Конструктор запроса». Платформа разберёт текст и либо откроет визуальный конструктор, либо укажет, в каком месте текст не разбирается.

Конструктор полезен тем, что:

  • показывает структуру запроса по вкладкам (таблицы, поля, связи, условия, итоги) — видно, не потеряна ли связь между таблицами;
  • не даёт собрать заведомо неверную конструкцию — например, выбрать несуществующее поле;
  • генерирует корректный текст с правильными псевдонимами и переносами.

Отдельно существует «Конструктор запроса с обработкой результата» — он дополнительно пишет цикл обхода выборки. Для проверки самого запроса он избыточен, берите обычный конструктор.

В 1С:EDT конструктор вызывается так же — из контекстного меню на тексте запроса, а структура показывается в отдельном редакторе. Дополнительно EDT подсвечивает многие ошибки прямо при наборе, не дожидаясь запуска: неизвестное поле или таблица помечаются сразу.

Конструктор ловит синтаксис, но не логику: он не знает, что вы хотели получить остатки на конец периода, а не обороты. Логику по-прежнему проверяют выполнением на реальных данных.

Как найти медленный запрос: замер производительности

Запрос может быть синтаксически верным и отдавать правильные данные, но тормозить на объёме. Чтобы понять, сколько времени он реально занимает, используйте замер производительности.

Порядок в конфигураторе:

  1. Запустите базу в режиме отладки (Отладка → Начать отладку или F5 из конфигуратора).
  2. Включите Отладка → Замер производительности.
  3. Выполните в 1С:Предприятии то действие, где работает запрос — откройте отчёт, проведите документ.
  4. Вернитесь в конфигуратор и остановите замер.

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

Замер отвечает на главный вопрос — виноват ли вообще запрос. Часто оказывается, что тормозит не он, а, например, получение данных в цикле или заполнение таблицы значений. Не оптимизируйте запрос, пока замер не подтвердил, что проблема в нём.

Если запрос действительно долгий, дальше нужно смотреть, что он превращается в на стороне СУБД.

Отладчик и просмотр реального SQL

В отладчике можно не только замерить время, но и посмотреть результат запроса и его SQL-текст, не меняя код.

Поставьте точку останова (breakpoint) на строке после выполнения запроса. Когда исполнение остановится:

  • наведите курсор на переменную результата или добавьте её в «Табло» — увидите выборку;
  • через Отладка → Вычислить выражение (Shift+F9) можно выполнить Результат.Выгрузить() и посмотреть таблицу целиком.

Чтобы увидеть реальный SQL-запрос, который платформа отправляет в СУБД, есть два пути:

  • Технологический журнал — настраивается файлом logcfg.xml. Нужны события DBMSSQL (текст SQL и длительность) и SDBL (запрос на внутреннем языке). В журнале видно и итоговый SQL, и время в микросекундах.
  • Консоль запросов в версии, умеющей показывать «запрос на языке СУБД» — проще, но без длительности на реальной нагрузке.

Минимальный logcfg.xml под разбор одного медленного запроса собирает только события работы с СУБД и ограничивает длительность, чтобы не писать быстрые обращения:

<log location="C:\tj" history="1">
  <event>
    <eq property="name" value="DBMSSQL"/>
    <ge property="duration" value="1000000"/>
  </event>
  <property name="all"/>
</log>

Здесь duration в микросекундах: 1000000 — это 1 секунда, то есть журнал запишет только запросы дольше секунды. Файл кладут в каталог conf платформы (путь зависит от версии и ОС), после чего агент сервера подхватывает настройку без перезапуска.

Технологический журнал пишет много данных и сам нагружает диск. Включайте его точечно — по конкретному событию и на короткое время, иначе за ночь набьёте десятки гигабайт логов. После разбора уберите logcfg.xml или очистите его содержимое.

Реальный SQL нужен для последнего шага — разбора плана выполнения на стороне сервера СУБД.

План выполнения и профайлер на стороне СУБД

План выполнения показывает, как сервер СУБД физически выполняет запрос: где идёт поиск по индексу, а где — полное сканирование таблицы. Именно сканирование больших таблиц чаще всего и даёт тормоза.

Для Microsoft SQL Server порядок такой:

  1. Из технологического журнала или консоли возьмите текст SQL-запроса.
  2. Откройте SQL Server Management Studio, вставьте запрос.
  3. Включите «Include Actual Execution Plan» и выполните.
  4. На вкладке плана ищите операции Table Scan и Index Scan по крупным таблицам, а также толстые стрелки — это большой поток строк.

SQL Server Profiler (или расширенные события, Extended Events) пригодится, когда надо поймать запрос в потоке: он фиксирует все обращения к базе с длительностью и числом чтений. По колонке Reads сразу видно самый «тяжёлый» запрос.

Для PostgreSQL логика та же, но план смотрят командой EXPLAIN ANALYZE перед текстом запроса, а медленные запросы ловят через auto_explain и лог долгих запросов.

Если своей экспертизы по планам не хватает, в состав КИП входит «Центр управления производительностью» (ЦУП) — он собирает статистику и подсвечивает проблемные запросы автоматически.

Тяжёлую диагностику лучше вести не на рабочей базе. Снятие плана и трассировка профайлером сами дают нагрузку, а подбор индексов на боевом сервере может задеть пользователей. Разбирайте медленные запросы на свежей копии рабочей базы — тогда и экспериментировать с условиями отбора можно свободно, не оглядываясь на тех, кто сейчас в системе.

Правило чтения плана простое: ищите, где обрабатывается больше всего строк, и проверяйте, есть ли по условию отбора подходящий индекс. Нет индекса — сервер читает всю таблицу.

Частые ошибки в запросах и как их исправить

Большинство проблем с запросами 1С укладывается в несколько повторяющихся шаблонов. Разберём их отдельно от инструментов — это ошибки проектирования текста, а не настройки.

Соединение с виртуальной таблицей. Отбор в виртуальной таблице (остатки, обороты) задают в её параметрах, а не в секции ГДЕ и не через СОЕДИНЕНИЕ. Если фильтр вынесен наружу, сервер сначала считает остатки по всем номенклатурам, а потом отбрасывает лишнее — отсюда тормоза. Правильно отбор выглядит так:

ВЫБРАТЬ
    ОстаткиТоваров.Номенклатура,
    ОстаткиТоваров.КоличествоОстаток
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки(
        ,
        Номенклатура В (&СписокНоменклатуры)) КАК ОстаткиТоваров

Список номенклатуры передан в параметр виртуальной таблицы — сервер отфильтрует данные ещё при расчёте остатков. Вынеси это же условие в ГДЕ — и выигрыша не будет.

Запрос в цикле. Классический антипаттерн: обход документов, и внутри на каждой итерации — новый запрос к базе. Правильно собрать все нужные данные одним запросом, а в цикле обходить готовую выборку. Проверить это легко: в замере производительности строка с Выполнить() будет показывать большое число вызовов — сотни и тысячи вместо одного.

Обращение через точку к полю составного типа. Конструкция вида Документ.Контрагент.ИНН, когда поле имеет составной тип, разворачивается платформой в набор соединений по всем таблицам типа. На объёме это дорого — лучше явные соединения с нужными таблицами.

Отбор по неиндексируемому полю. Условие ГДЕ по полю, которое не входит в индекс, заставляет сервер сканировать таблицу целиком. Проверяется это как раз планом выполнения.

Потеря связи между таблицами. При нескольких источниках легко забыть условие соединения — результат раздувается декартовым произведением. Конструктор запроса на вкладке связей показывает это наглядно.

Типовые синтаксические ошибки и что они означают:

Текст ошибкиПричинаЧто сделать
Поле не найдено «…»опечатка в имени реквизита или неверный псевдоним таблицысверить имя с деревом метаданных
Ожидается выражениепропущена запятая, скобка или операторпроверить строку, указанную в ошибке
Таблица не найденаневерное имя таблицы или регистраоткрыть конструктор и выбрать таблицу из списка
Параметры не заданыв тексте есть &Параметр, но значение не переданозадать параметр в консоли или в коде

Для диагностики по симптому держите под рукой короткий чек-лист.

Проверка запроса перед боевой базой
Выполнено: 0 / 7

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

Можно ли проверить запрос, не открывая конфигуратор?
Да. Консоль запросов — внешняя обработка, она работает в режиме 1С:Предприятие и не требует конфигуратора. Нужно только право на открытие внешних обработок у вашего пользователя.
Чем отличается конструктор запроса от консоли запросов?
Конструктор собирает и проверяет текст запроса визуально в конфигураторе или EDT — он ловит синтаксис. Консоль выполняет готовый запрос на реальных данных и показывает результат — она проверяет логику и скорость.
Как посмотреть, в какой SQL превращается запрос 1С?
Через технологический журнал с событием DBMSSQL — там виден итоговый текст на языке СУБД и длительность. Некоторые версии консоли запросов тоже умеют показывать «запрос на языке СУБД».
Замер производительности показал, что медленно, но не запрос. Что дальше?
Значит, время уходит на другую строку кода — чаще всего на обработку выборки в цикле или заполнение таблицы значений. Оптимизируйте именно её; трогать сам запрос в этом случае бесполезно.
Нужны ли права администратора, чтобы снять план выполнения в SQL Server?
Для чтения плана в SSMS достаточно прав на выполнение запроса к рабочей базе. Для запуска трассировки через Profiler или расширенные события нужны серверные права — это обычно делает администратор СУБД.