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

· 9 мин

Содержание

Проверить запрос в 1С — значит ответить на три разных вопроса: верен ли синтаксис, те ли данные он возвращает и не тормозит ли он на реальном объёме. Для каждого есть свой инструмент: синтаксис ловит конструктор запроса, результат показывает консоль запросов или отладчик, а скорость видно только в плане выполнения SQL и замере производительности.

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

С чего начать проверку: три слоя одной задачи

Разделите задачу сразу, иначе будете искать ошибку не там.

  • 🧩 Синтаксис. Запрос не компилируется, платформа ругается на текст. Решается в конструкторе или прямо в модуле.
  • 📊 Логика. Запрос выполняется, но строк не то число, суммы не сходятся, дубли. Смотрят через выполнение на реальных данных.
  • 🐢 Производительность. Результат верный, но форма открывается 40 секунд. Нужен текст SQL и план его выполнения.

Девять из десяти «странных» результатов — это соединения. Левое соединение с виртуальной таблицей остатков, условие в ПО вместо ГДЕ, потерянная группировка. Проверку логики почти всегда стоит начинать с блока СОЕДИНЕНИЕ.

Инструменты работают в двух режимах. Конструктор и консоль — это 1С:Предприятие, туда пускают с обычными правами. Отладчик, техжурнал и замер производительности живут в конфигураторе и требуют прав на отладку и доступа к файлам платформы.

Ещё одна развилка — СУБД. На файловой базе отдельного SQL-плана нет, платформа работает со своим форматом файлов, поэтому анализ плана доступен только в клиент-серверном варианте на MS SQL Server или PostgreSQL. Логику и синтаксис при этом проверяют одинаково в любой базе, а вот тонкую оптимизацию запроса делают там, где видят план СУБД.

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

Самый быстрый способ — отдать текст конструктору. Он не только рисует запрос мышью, но и разбирает уже написанный.

В модуле поставьте курсор внутрь строки с текстом запроса, нажмите правую кнопку и выберите Конструктор запроса. Если текст корректен — откроется визуальная схема с таблицами, полями и соединениями. Если есть ошибка синтаксиса, конструктор откажется открываться и покажет позицию проблемы: лишнюю запятую, незакрытую скобку, неизвестное поле.

Так проверяют и логику построения:

  1. Откройте готовый текст в конструкторе.
  2. Перейдите на закладку Соединения — увидите, какое соединение левое, какое внутреннее, и по каким полям.
  3. Закладка Группировка покажет, по каким полям идёт СГРУППИРОВАТЬ ПО и какие поля агрегируются.
  4. Закладка Условия — весь блок ГДЕ и параметры.

Часто ошибка видна глазами именно в схеме: поле попало в группировку вместо агрегатной функции, соединение оказалось внутренним и отрезало часть строк.

Конструктор переформатирует текст и может переставить поля. Если у вас аккуратно оформленный запрос с комментариями — сделайте копию перед тем, как «прогнать» его через конструктор, иначе комментарии и ручное форматирование потеряются.

Для схемы компоновки данных аналог — Конструктор схемы компоновки данных, он проверяет текст запроса СКД точно так же.

Как увидеть текст SQL, который уходит в СУБД

Язык запросов 1С — это не SQL. Платформа переводит его в SQL своего диалекта (для MS SQL Server или PostgreSQL) и подставляет реальные имена таблиц вида _Reference123. Из кода этот SQL напрямую не достать — нет метода «дай мне текст запроса на SQL». Его собирают снаружи.

Технологический журнал. Это штатный механизм платформы. В каталоге conf платформы (путь вида C:\Program Files\1cv8\conf\) создаётся файл logcfg.xml, в нём включается событие DBMSSQL — это и есть текст запроса к СУБД. В записи события вы увидите готовый SQL с подставленными параметрами и длительность выполнения в микросекундах.

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

Замер производительности в конфигураторе. Для прикладного кода удобнее он. В конфигураторе: меню Отладка → Замер производительности. Запускаете замер, воспроизводите медленную операцию в 1С:Предприятии, останавливаете. Платформа покажет строки кода с их длительностью. Для строки с запросом в контекстном меню доступен просмотр текста запроса и его SQL-представления.

Средства СУБД. На MS SQL Server текст и план ловят через SQL Server Profiler или Extended Events. На PostgreSQL — через лог медленных запросов (log_min_duration_statement) и команду EXPLAIN ANALYZE. Этим пользуются администраторы, когда нужен не отдельный запрос, а общая картина нагрузки.

Собрать текст SQL по медленной операции
Выполнено: 0 / 5

Пошаговый разбор запроса в отладчике

Когда запрос формально верен, а в таблицу попадает не то — нужно остановиться прямо на строке и посмотреть результат вживую.

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

Главный приём — окно Вычислить выражение (Shift+F9). В нём можно выполнить любое выражение в текущем контексте и сразу увидеть таблицу значений. Например, прямо на паузе напишите:

Запрос.Выполнить().Выгрузить()

и нажмите «Рассчитать» — получите результат запроса в виде таблицы, по строкам и колонкам, не прерывая отладку. Так за секунды видно, что соединение отрезало строки или параметр пришёл пустым.

Полезный код для самопроверки запроса целиком:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Номенклатура.Ссылка КАК Номенклатура,
|    ОстаткиОстаток.ВНаличииОстаток КАК Остаток
|ИЗ
|    Справочник.Номенклатура КАК Номенклатура
|    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&МоментВремени) КАК ОстаткиОстаток
|    ПО ОстаткиОстаток.Номенклатура = Номенклатура.Ссылка";
Запрос.УстановитьПараметр("МоментВремени", ТекущаяДата());
Результат = Запрос.Выполнить();
Таблица = Результат.Выгрузить();

Поставьте точку останова на последней строке, дойдите до неё и посмотрите Таблица в табло. Если строк меньше ожидаемого — ищите причину в соединении; если Остаток везде пустой — дело в моменте времени или параметре.

Если переменной Запрос в точке останова ещё нет (код до её объявления), окно Вычислить выражение подсветит это как неизвестный идентификатор. Останавливайтесь на строке, где переменная уже заполнена.

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

Отладчик хорош, когда запрос зашит в код. Если нужно просто покрутить текст запроса на живой базе — быстрее консоль запросов.

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

Что даёт консоль:

  • 📝 Поле для текста запроса со встроенным конструктором — тем же, что в конфигураторе.
  • 🔢 Автоматический разбор параметров: вписали &Период — консоль сама предложит ввести его значение и тип.
  • 📋 Результат в табличном поле, который можно отсортировать, отфильтровать и выгрузить.
  • ⏱ Время выполнения запроса — грубый, но мгновенный ориентир «быстро/медленно».

Рабочий цикл простой: вставили текст, задали параметры, выполнили, посмотрели строки. Меняете условие — выполняете снова. Проверять логику так в разы быстрее, чем через отладчик, потому что не нужно каждый раз воспроизводить сценарий в прикладном решении.

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

Анализ плана выполнения и ускорение запроса

Запрос верный, но медленный — значит, СУБД выбрала неудачный план. План выполнения показывает, как именно сервер БД достаёт данные: сканирует таблицу целиком или идёт по индексу, в каком порядке соединяет.

Где смотреть план:

  • MS SQL Server — в SQL Server Management Studio выполнить собранный из техжурнала SQL с включённым Include Actual Execution Plan.
  • PostgreSQL — команда EXPLAIN ANALYZE перед текстом запроса.

Красные флаги в плане почти везде одинаковы: полное сканирование большой таблицы (Table Scan / Seq Scan) там, где ждёшь индекс; соединение большого числа строк; сортировка миллионов записей.

Типичные причины медленного запроса 1С и что с ними делать:

СимптомВероятная причинаЧто проверить
Сканируется вся таблицаНет отбора по индексируемому полюДобавить условие по измерению/периоду
Долгое соединениеСоединение с подзапросом или виртуальной таблицей без отбораВынести во временную таблицу, задать отбор в параметрах вирт. таблицы
Много строк на входеОтбор стоит в ПО, а не в ГДЕПеренести условие по данным в ГДЕ
Запрос «раздувает» строкиСоединение по неуникальному полюПроверить кратность, добавить РАЗЛИЧНЫЕ осознанно

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

ВЫБРАТЬ
    Товары.Ссылка КАК Номенклатура
ПОМЕСТИТЬ ВТ_Товары
ИЗ
    Справочник.Номенклатура КАК Товары
ГДЕ
    Товары.Родитель = &Группа
;
ВЫБРАТЬ
    ВТ_Товары.Номенклатура КАК Номенклатура,
    Остатки.ВНаличииОстаток КАК Остаток
ИЗ
    ВТ_Товары КАК ВТ_Товары
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК Остатки
    ПО Остатки.Номенклатура = ВТ_Товары.Номенклатура

Разница с «одним большим запросом» на объёме в сотни тысяч строк бывает в разы: СУБД сначала отбирает узкий список товаров, и виртуальная таблица остатков считается только по ним.

Приёмы, которые дают основной выигрыш:

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

Перед оптимизацией снимите цифру «было»: длительность в консоли или в замере производительности. После правки замерьте «стало» на том же объёме данных. Без двух чисел вы не знаете, помогло ли.

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

  • ❌ Проверяют на пустой базе. На трёх тестовых записях любой запрос летает. Планы SQL и тормоза проявляются только на реальном объёме — проверяйте на копии рабочей базы.
  • ❌ Тестируют под админом. Полные права обходят RLS. «У меня всё видно» под администратором ничего не говорит о том, что увидит пользователь.
  • ❌ Забывают про момент времени. Виртуальная таблица остатков без корректного &МоментВремени или с Неопределено даёт остатки «на конец», а не на нужную дату — и цифры «не те».
  • ❌ Оставляют включённый техжурнал. Забытый logcfg.xml на боевом сервере месяцами пишет гигабайты логов и сам тормозит систему.
  • ❌ Меняют запрос и план сразу. Правят три вещи разом, получают результат и не знают, что именно сработало. Меняйте по одному и замеряйте.
Можно ли увидеть SQL-текст запроса прямо из кода 1С?
Нет, штатного метода, возвращающего SQL, в языке нет. Текст к СУБД получают снаружи: через технологический журнал (событие DBMSSQL), замер производительности в конфигураторе или средствами самой СУБД.
Чем конструктор запроса отличается от консоли запросов?
Конструктор проверяет и строит текст запроса, но не выполняет его на данных. Консоль — выполняет: подставляет параметры, показывает результат в таблице и время работы. На практике их используют вместе.
Почему запрос в консоли выдаёт строки, а у пользователя — нет?
Скорее всего, дело в правах и ограничении доступа на уровне записей (RLS). Запрос исполняется в контексте пользователя. Проверьте тот же запрос под ролью этого пользователя, а не под полными правами.
Нужны ли права администратора, чтобы проверить запрос?
Для конструктора и консоли — нет, хватает обычного доступа к 1С:Предприятию. Для отладчика, замера производительности и техжурнала нужны права на отладку и доступ к файлам платформы на сервере.
Как быстро понять, медленный запрос или нет?
Выполните его в консоли запросов — она покажет время. Если счёт идёт на секунды и растёт с объёмом данных, снимайте план выполнения и ищите полное сканирование таблиц.