Зачем описывать поля в расширении языка запросов СКД для временных таблиц?

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

При разработке сложных отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с необходимостью тонкой настройки запросов. Одним из таких инструментов является расширение языка запросов — специальные конструкции в фигурных скобках {}. Особый интерес вызывает вопрос: имеет ли смысл использовать конструкцию {ВЫБРАТЬ...} внутри временных таблиц, особенно когда флажок "Автозаполнение" в схеме компоновки выключен? Давайте подробно разберем этот механизм, проанализируем поведение платформы и выясним, как это влияет на производительность и структуру итогового запроса.

Механизм расширения языка запросов в СКД

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

Рассмотрим стандартную структуру пакета запросов, состоящую из создания временной таблицы (ВТ) и основного запроса, который из этой таблицы выбирает данные. На практике часто возникает вопрос: если мы описываем поля компоновки в основном запросе, нужно ли дублировать их в тексте запроса, создающего временную таблицу?

Анализ влияния конструкции {ВЫБРАТЬ...} во временных таблицах

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


ВЫБРАТЬ
    ХозрасчетныйОстатки.Субконто1 КАК Номенклатура,
    ХозрасчетныйОстатки.Субконто2 КАК Склад,
    ХозрасчетныйОстатки.КоличествоОстатокДт КАК Количество,
    ХозрасчетныйОстатки.СуммаОстатокДт КАК Стоимость
ПОМЕСТИТЬ ВТ_Остатки
{ВЫБРАТЬ
    Номенклатура.*,
    Склад.*,
    Количество,
    Стоимость}
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, Счет = &Счет, , ) КАК ХозрасчетныйОстатки;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Остатки.Номенклатура,
    ВТ_Остатки.Склад,
    ВТ_Остатки.Количество,
    ВТ_Остатки.Стоимость
{ВЫБРАТЬ
    Номенклатура.*,
    Склад.*,
    Количество,
    Стоимость}
ИЗ
    ВТ_Остатки КАК ВТ_Остатки

Проанализируем результаты экспериментов. Если мы укажем дополнительные поля в блоке {ВЫБРАТЬ...} первой части запроса (где создается ВТ), но не используем их в финальной выборке и не выводим в отчет, оптимизатор СКД их проигнорирует. Платформа 1С стремится минимизировать нагрузку на SQL-сервер и объем данных, записываемых в tempdb. Таким образом, простое наличие поля в расширении ВЫБРАТЬ временной таблицы само по себе не заставляет систему тащить это поле через весь пакет запросов.

Однако есть важный нюанс: описание поля в {ВЫБРАТЬ...} временной таблицы может влиять на список доступных полей в конструкторе настроек СКД. Если поле описано в ВТ, но забыто в основном запросе, оно может отобразиться в списке доступных, но при попытке его вывода отчет может выдать ошибку или пустой результат, так как связь между временной таблицей и итоговым результатом не будет простроена автоматически.

Критическая важность конструкции {ГДЕ...} во временных таблицах

В отличие от {ВЫБРАТЬ...}, использование расширения {ГДЕ...} (условия) во временных таблицах имеет решающее значение для производительности. Рассмотрим, почему это так. Выясним причину, по которой отборы часто работают медленно.

Если пользователь устанавливает отбор по полю "Склад", и это поле описано только в финальном запросе, СКД применит условие WHERE к результату объединения или к выборке из уже готовой временной таблицы. Это означает, что во временную таблицу попадут остатки по всем складам, и только потом они будут отфильтрованы. Если же мы укажем {ГДЕ Склад.*} в запросе создания ВТ, компоновщик «пробросит» условие пользователя непосредственно в первый запрос. В итоге временная таблица будет содержать данные только по нужному складу, что в разы ускорит выполнение отчета.

Зачем же разработчики 1С оставляют {ВЫБРАТЬ...} в ВТ в типовых решениях?

При изучении типовых конфигураций, таких как ERP или УТ 11, можно заметить избыточное описание полей в расширениях запросов временных таблиц. Рассмотрим основные причины такого подхода:

  1. Особенности работы конструктора: Визуальный конструктор запросов СКД часто дублирует настройки компоновки при копировании частей запроса или при изменении структуры пакета. Разработчики не всегда удаляют эти конструкции вручную, так как они не вредят производительности (благодаря оптимизатору), но позволяют сохранить структуру метаданных.
  2. Гибкость при модификации: Если в будущем программисту потребуется «вытащить» дополнительное поле из временной таблицы в основной запрос, наличие уже готового описания в {ВЫБРАТЬ...} упрощает эту задачу. Поле уже определено в терминах компоновки, и его достаточно просто добавить в список выборки последнего запроса.
  3. Типизация полей: В некоторых случаях описание полей в фигурных скобках помогает системе корректно определить типы данных, особенно если поле является результатом сложного выражения или вызова функции. Это обеспечивает правильную работу заголовков и форматных строк в отчете.

Практические рекомендации по настройке запросов СКД

На основе вышеизложенного, выработаем алгоритм действий при работе с расширениями языка запросов во временных таблицах:

Рассмотрим пример правильного описания условия во временной таблице, чтобы отбор применялся максимально эффективно:


ВЫБРАТЬ
    ПродажиОбороты.Номенклатура КАК Номенклатура,
    ПродажиОбороты.КоличествоОборот КАК Количество
ПОМЕСТИТЬ ВТ_Данные
ИЗ
    РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , {Номенклатура.* КАК Номенклатура}) КАК ПродажиОбороты
{ГДЕ
    ПродажиОбороты.Номенклатура.* КАК Номенклатура}

В данном примере использование {ГДЕ...} позволит СКД вставить условие непосредственно в параметры виртуальной таблицы или в секцию WHERE при формировании временной таблицы, что является эталоном оптимизации в 1С.

Резюме

Подводя итог, можно сказать, что возможность задавать поля в секции {ВЫБРАТЬ...} для временных таблиц — это скорее следствие универсальности конструктора запросов, нежели реальная необходимость. Это не является ошибкой, но и не дает ощутимых преимуществ в большинстве сценариев. В то же время, грамотное использование секции {ГДЕ...} в тех же временных таблицах является признаком профессионального подхода к разработке на платформе 1С:Предприятие 8.3.

← На главную