Диагностика запроса 1С: от синтаксиса до плана выполнения
Содержание
Быстрее всего проверить запрос в 1С так: откройте консоль запросов, вставьте текст, подставьте параметры и нажмите «Выполнить». Результат и ошибка синтаксиса появятся сразу, без изменения кода конфигурации. Если запрос отдаёт верные данные, но работает медленно — включите замер производительности в отладчике и посмотрите реальный SQL.
Проверка запроса распадается на три независимые задачи: синтаксис (текст разбирается без ошибок), логика (данные те, что нужны) и производительность (запрос не висит на боевой базе). Для каждой — свой инструмент. Ниже разберём, чем проверять запрос на каждом уровне, как увидеть план выполнения на стороне СУБД и какие ошибки в тексте встречаются чаще всего.
Какой инструмент выбрать под задачу
Прежде чем лезть в код, определитесь, что именно вы проверяете. От этого зависит инструмент.
Дальше — каждый инструмент по порядку, от простого к глубокому.
Проверка в консоли запросов
Консоль запросов — внешняя обработка (.epf), которая выполняет произвольный запрос прямо в режиме 1С:Предприятие, без выхода в конфигуратор. Это самый быстрый способ проверить и текст, и результат.
Чтобы её открыть:
- Возьмите обработку «Консоль запросов» из комплекта стандартных обработок (она идёт в составе дисков ИТС и типовых поставок).
- В 1С:Предприятии зайдите в
Файл → Открытьи укажите файл обработки. - В поле текста вставьте запрос, при необходимости задайте параметры на отдельной вкладке.
- Нажмите «Выполнить» — результат появится в таблице внизу.
Открытие внешних обработок требует соответствующего права у пользователя. Если пункт Файл → Открыть недоступен, попросите администратора выдать роль с правом на интерактивное открытие внешних обработок — на боевой базе это ограничивают намеренно.
Что консоль показывает:
- 🔴 ошибку синтаксиса с указанием позиции в тексте — например «Поле не найдено» или «Ожидается выражение»;
- 📊 таблицу результата — можно сразу сверить цифры с отчётом;
- ⏱ время выполнения запроса в миллисекундах (в большинстве версий консоли).
Для разовой проверки логики консоли достаточно: подставили параметры периода и организации, выполнили, глазами сравнили итог с оборотно-сальдовой ведомостью.
Многие версии консоли умеют показывать текст запроса на языке СУБД и временные таблицы. Это пригодится, когда дойдёте до разбора производительности.
Отдельно стоит проверять пакетные запросы — те, что собирают несколько временных таблицы через ПОМЕСТИТЬ. В консоли такой пакет выполняется целиком, и после прогона видно содержимое каждой временной таблицы. Это удобный способ поймать ошибку на промежуточном шаге: часто неверные данные появляются не в финальной выборке, а в одной из временных таблиц по дороге.
Проверка синтаксиса через конструктор запроса
Если запрос пишется в коде модуля, синтаксис проще проверять конструктором запроса. Он доступен в конфигураторе и в 1С:EDT.
В конфигураторе поставьте курсор внутрь строки с текстом запроса, нажмите правую кнопку мыши и выберите «Конструктор запроса». Платформа разберёт текст и либо откроет визуальный конструктор, либо укажет, в каком месте текст не разбирается.
Конструктор полезен тем, что:
- показывает структуру запроса по вкладкам (таблицы, поля, связи, условия, итоги) — видно, не потеряна ли связь между таблицами;
- не даёт собрать заведомо неверную конструкцию — например, выбрать несуществующее поле;
- генерирует корректный текст с правильными псевдонимами и переносами.
Отдельно существует «Конструктор запроса с обработкой результата» — он дополнительно пишет цикл обхода выборки. Для проверки самого запроса он избыточен, берите обычный конструктор.
В 1С:EDT конструктор вызывается так же — из контекстного меню на тексте запроса, а структура показывается в отдельном редакторе. Дополнительно EDT подсвечивает многие ошибки прямо при наборе, не дожидаясь запуска: неизвестное поле или таблица помечаются сразу.
Конструктор ловит синтаксис, но не логику: он не знает, что вы хотели получить остатки на конец периода, а не обороты. Логику по-прежнему проверяют выполнением на реальных данных.
Как найти медленный запрос: замер производительности
Запрос может быть синтаксически верным и отдавать правильные данные, но тормозить на объёме. Чтобы понять, сколько времени он реально занимает, используйте замер производительности.
Порядок в конфигураторе:
- Запустите базу в режиме отладки (
Отладка → Начать отладкуили F5 из конфигуратора). - Включите
Отладка → Замер производительности. - Выполните в 1С:Предприятии то действие, где работает запрос — откройте отчёт, проведите документ.
- Вернитесь в конфигуратор и остановите замер.
Платформа покажет таблицу: каждая строка кода, сколько раз выполнялась и сколько миллисекунд заняла. Строка с запросом, съедающая основное время, видна сразу.
Замер отвечает на главный вопрос — виноват ли вообще запрос. Часто оказывается, что тормозит не он, а, например, получение данных в цикле или заполнение таблицы значений. Не оптимизируйте запрос, пока замер не подтвердил, что проблема в нём.
Если запрос действительно долгий, дальше нужно смотреть, что он превращается в на стороне СУБД.
Отладчик и просмотр реального 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 порядок такой:
- Из технологического журнала или консоли возьмите текст SQL-запроса.
- Откройте SQL Server Management Studio, вставьте запрос.
- Включите «Include Actual Execution Plan» и выполните.
- На вкладке плана ищите операции
Table ScanиIndex Scanпо крупным таблицам, а также толстые стрелки — это большой поток строк.
SQL Server Profiler (или расширенные события, Extended Events) пригодится, когда надо поймать запрос в потоке: он фиксирует все обращения к базе с длительностью и числом чтений. По колонке Reads сразу видно самый «тяжёлый» запрос.
Для PostgreSQL логика та же, но план смотрят командой EXPLAIN ANALYZE перед текстом запроса, а медленные запросы ловят через auto_explain и лог долгих запросов.
Если своей экспертизы по планам не хватает, в состав КИП входит «Центр управления производительностью» (ЦУП) — он собирает статистику и подсвечивает проблемные запросы автоматически.
Тяжёлую диагностику лучше вести не на рабочей базе. Снятие плана и трассировка профайлером сами дают нагрузку, а подбор индексов на боевом сервере может задеть пользователей. Разбирайте медленные запросы на свежей копии рабочей базы — тогда и экспериментировать с условиями отбора можно свободно, не оглядываясь на тех, кто сейчас в системе.
Правило чтения плана простое: ищите, где обрабатывается больше всего строк, и проверяйте, есть ли по условию отбора подходящий индекс. Нет индекса — сервер читает всю таблицу.
Частые ошибки в запросах и как их исправить
Большинство проблем с запросами 1С укладывается в несколько повторяющихся шаблонов. Разберём их отдельно от инструментов — это ошибки проектирования текста, а не настройки.
Соединение с виртуальной таблицей. Отбор в виртуальной таблице (остатки, обороты) задают в её параметрах, а не в секции ГДЕ и не через СОЕДИНЕНИЕ. Если фильтр вынесен наружу, сервер сначала считает остатки по всем номенклатурам, а потом отбрасывает лишнее — отсюда тормоза. Правильно отбор выглядит так:
ВЫБРАТЬ
ОстаткиТоваров.Номенклатура,
ОстаткиТоваров.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(
,
Номенклатура В (&СписокНоменклатуры)) КАК ОстаткиТоваров
Список номенклатуры передан в параметр виртуальной таблицы — сервер отфильтрует данные ещё при расчёте остатков. Вынеси это же условие в ГДЕ — и выигрыша не будет.
Запрос в цикле. Классический антипаттерн: обход документов, и внутри на каждой итерации — новый запрос к базе. Правильно собрать все нужные данные одним запросом, а в цикле обходить готовую выборку. Проверить это легко: в замере производительности строка с Выполнить() будет показывать большое число вызовов — сотни и тысячи вместо одного.
Обращение через точку к полю составного типа. Конструкция вида Документ.Контрагент.ИНН, когда поле имеет составной тип, разворачивается платформой в набор соединений по всем таблицам типа. На объёме это дорого — лучше явные соединения с нужными таблицами.
Отбор по неиндексируемому полю. Условие ГДЕ по полю, которое не входит в индекс, заставляет сервер сканировать таблицу целиком. Проверяется это как раз планом выполнения.
Потеря связи между таблицами. При нескольких источниках легко забыть условие соединения — результат раздувается декартовым произведением. Конструктор запроса на вкладке связей показывает это наглядно.
Типовые синтаксические ошибки и что они означают:
| Текст ошибки | Причина | Что сделать |
|---|---|---|
| Поле не найдено «…» | опечатка в имени реквизита или неверный псевдоним таблицы | сверить имя с деревом метаданных |
| Ожидается выражение | пропущена запятая, скобка или оператор | проверить строку, указанную в ошибке |
| Таблица не найдена | неверное имя таблицы или регистра | открыть конструктор и выбрать таблицу из списка |
| Параметры не заданы | в тексте есть &Параметр, но значение не передано | задать параметр в консоли или в коде |
Для диагностики по симптому держите под рукой короткий чек-лист.
Частые вопросы
Можно ли проверить запрос, не открывая конфигуратор?
Чем отличается конструктор запроса от консоли запросов?
Как посмотреть, в какой SQL превращается запрос 1С?
DBMSSQL — там виден итоговый текст на языке СУБД и длительность. Некоторые версии консоли запросов тоже умеют показывать «запрос на языке СУБД».