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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с крупными конфигурациями или сложными аналитическими отчетами разработчики часто сталкиваются с ситуацией, когда текст запроса разрастается до внушительных размеров — 1000 строк и более. В таких случаях может возникнуть странный эффект: запрос выполняется долго (например, 5 секунд), даже если данных в базе почти нет, а индексы настроены корректно. Самое примечательное, что даже при наличии синтаксической ошибки платформа «задумывается» на те же 5 секунд, прежде чем выдать сообщение об ошибке. Рассмотрим подробнее, почему это происходит и как это исправить.

Выясняем причину: почему запрос «тормозит» еще до начала выполнения

Проанализируем ситуацию, описанную в теме. Если задержка происходит даже при возникновении ошибки, это верный признак того, что время тратится не на обращение к СУБД, а на трансляцию и синтаксический анализ запроса самой платформой 1С. Разберем по шагам, что происходит «под капотом»:

  1. Построение дерева запроса (AST): Когда платформа получает текст запроса, она строит внутреннее объектное дерево (Abstract Syntax Tree). Для огромных текстов с множеством соединений (ЛЕВОЕ СОЕДИНЕНИЕ) и объединений (ОБЪЕДИНИТЬ ВСЕ) глубина этого дерева становится критической.
  2. Проверка метаданных и прав: Парсер 1С сопоставляет каждое поле в запросе с объектами метаданных, проверяет типы данных и накладывает ограничения прав доступа (RLS). Чем больше строк, тем больше обращений к кэшу метаданных.
  3. Особенности файловой базы: В файловом варианте движок подготовки плана выполнения менее эффективен, чем в промышленных СУБД (MS SQL, PostgreSQL). При достижении порога в 500–1000 строк время анализа текста растет не линейно, а экспоненциально.

Таким образом, мы имеем дело с проблемой «длинной компиляции». Чтобы вылечить эту «дичь», нужно упростить задачу для парсера платформы.

Решение 1: Разделение монолитного запроса на пакеты через временные таблицы

Это самый эффективный способ ускорить анализ запроса. Вместо того чтобы заставлять 1С строить одно гигантское дерево для 1000 строк кода, мы разделим его на логические этапы. Рассмотрим, как это сделать с помощью МенеджерВременныхТаблиц.

Когда запрос разбит на пакеты (разделенные символом ;), платформа анализирует каждую часть последовательно. Это значительно снижает нагрузку на оптимизатор. Выясним, как преобразовать ваш код:


// Создаем менеджер временных таблиц
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

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

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

// Часть 2: Основная логика с использованием подготовленных данных
Запрос.Текст = 
"ВЫБРАТЬ
|	ВТ.ДокументСсылка,
|	ВТ.Сумма,
|	ЕСТЬNULL(ДопСведения.Значение, 0) КАК ДопПоле
|ИЗ
|	ВТ_ОсновныеДанные КАК ВТ
|	ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДопСведения
|	ПО ВТ.ДокументСсылка = ДопСведения.Объект";

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

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

Решение 2: Проверка на избыточность и «генерационный» мусор

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

Помните: каждое лишнее поле в ВЫБРАТЬ — это дополнительная работа для парсера по проверке прав доступа, даже если RLS у вас отключен. Платформа все равно обязана проверить схему.

Решение 3: Использование инструментов анализа (Консоль запросов)

Чтобы понять, какая именно часть вашего 1000-строчного монстра тормозит, используйте профессиональные инструменты, такие как ИР (Инструменты Разработчика). Посмотрим на алгоритм действий:

  1. Загрузите текст запроса в консоль.
  2. Выполняйте его пошагово (если это пакетный запрос).
  3. Посмотрите на время «подготовки» и время «выполнения».
  4. Если время подготовки (до появления первой строки в консоли) велико — возвращайтесь к Решению 1.

Решение 4: Переход на клиент-серверный вариант (SQL)

Файловая база данных имеет свои пределы. Как было отмечено в обсуждении, файловые базы хороши для небольших внедрений или демонстраций. Если ваша бизнес-логика требует обработки запросов по 1000 строк с кучей проверок, проанализируем возможность перехода на MS SQL или PostgreSQL. Серверные СУБД гораздо лучше справляются с кэшированием планов выполнения. Если один и тот же сложный запрос выполняется часто, SQL-сервер сохранит его план, и повторные запуски (при использовании параметров) будут проходить мгновенно.

Рекомендации по написанию «тяжелых» запросов

Сформулируем основные правила, которые помогут избежать пятисекундных задержек:

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

← На главную