При разработке сложных отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с необходимостью тонкой настройки запросов. Одним из таких инструментов является расширение языка запросов — специальные конструкции в фигурных скобках {}. Особый интерес вызывает вопрос: имеет ли смысл использовать конструкцию {ВЫБРАТЬ...} внутри временных таблиц, особенно когда флажок "Автозаполнение" в схеме компоновки выключен? Давайте подробно разберем этот механизм, проанализируем поведение платформы и выясним, как это влияет на производительность и структуру итогового запроса.
Для начала вспомним, для чего вообще нужны фигурные скобки. Когда мы отключаем автоматическое заполнение доступных полей, мы берем на себя ответственность за то, какие поля будут доступны пользователю для выбора, группировки и отбора. Расширение языка запросов позволяет явно указать компоновщику макета, в какие места запроса он может «вклиниться» для добавления дополнительных полей или условий.
Рассмотрим стандартную структуру пакета запросов, состоящую из создания временной таблицы (ВТ) и основного запроса, который из этой таблицы выбирает данные. На практике часто возникает вопрос: если мы описываем поля компоновки в основном запросе, нужно ли дублировать их в тексте запроса, создающего временную таблицу?
Разберем ситуацию на примере запроса, который подготавливает данные по остаткам и стоимости номенклатуры. Проанализируем, как ведет себя система при наличии описания полей во временной таблице:
ВЫБРАТЬ
ХозрасчетныйОстатки.Субконто1 КАК Номенклатура,
ХозрасчетныйОстатки.Субконто2 КАК Склад,
ХозрасчетныйОстатки.КоличествоОстатокДт КАК Количество,
ХозрасчетныйОстатки.СуммаОстатокДт КАК Стоимость
ПОМЕСТИТЬ ВТ_Остатки
{ВЫБРАТЬ
Номенклатура.*,
Склад.*,
Количество,
Стоимость}
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, Счет = &Счет, , ) КАК ХозрасчетныйОстатки;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_Остатки.Номенклатура,
ВТ_Остатки.Склад,
ВТ_Остатки.Количество,
ВТ_Остатки.Стоимость
{ВЫБРАТЬ
Номенклатура.*,
Склад.*,
Количество,
Стоимость}
ИЗ
ВТ_Остатки КАК ВТ_Остатки
Проанализируем результаты экспериментов. Если мы укажем дополнительные поля в блоке {ВЫБРАТЬ...} первой части запроса (где создается ВТ), но не используем их в финальной выборке и не выводим в отчет, оптимизатор СКД их проигнорирует. Платформа 1С стремится минимизировать нагрузку на SQL-сервер и объем данных, записываемых в tempdb. Таким образом, простое наличие поля в расширении ВЫБРАТЬ временной таблицы само по себе не заставляет систему тащить это поле через весь пакет запросов.
Однако есть важный нюанс: описание поля в {ВЫБРАТЬ...} временной таблицы может влиять на список доступных полей в конструкторе настроек СКД. Если поле описано в ВТ, но забыто в основном запросе, оно может отобразиться в списке доступных, но при попытке его вывода отчет может выдать ошибку или пустой результат, так как связь между временной таблицей и итоговым результатом не будет простроена автоматически.
В отличие от {ВЫБРАТЬ...}, использование расширения {ГДЕ...} (условия) во временных таблицах имеет решающее значение для производительности. Рассмотрим, почему это так. Выясним причину, по которой отборы часто работают медленно.
Если пользователь устанавливает отбор по полю "Склад", и это поле описано только в финальном запросе, СКД применит условие WHERE к результату объединения или к выборке из уже готовой временной таблицы. Это означает, что во временную таблицу попадут остатки по всем складам, и только потом они будут отфильтрованы. Если же мы укажем {ГДЕ Склад.*} в запросе создания ВТ, компоновщик «пробросит» условие пользователя непосредственно в первый запрос. В итоге временная таблица будет содержать данные только по нужному складу, что в разы ускорит выполнение отчета.
При изучении типовых конфигураций, таких как ERP или УТ 11, можно заметить избыточное описание полей в расширениях запросов временных таблиц. Рассмотрим основные причины такого подхода:
{ВЫБРАТЬ...} упрощает эту задачу. Поле уже определено в терминах компоновки, и его достаточно просто добавить в список выборки последнего запроса.На основе вышеизложенного, выработаем алгоритм действий при работе с расширениями языка запросов во временных таблицах:
Остатки или Обороты) внутри временных таблиц, обязательно дублируйте параметры и условия в расширениях именно там.Рассмотрим пример правильного описания условия во временной таблице, чтобы отбор применялся максимально эффективно:
ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.КоличествоОборот КАК Количество
ПОМЕСТИТЬ ВТ_Данные
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , {Номенклатура.* КАК Номенклатура}) КАК ПродажиОбороты
{ГДЕ
ПродажиОбороты.Номенклатура.* КАК Номенклатура}
В данном примере использование {ГДЕ...} позволит СКД вставить условие непосредственно в параметры виртуальной таблицы или в секцию WHERE при формировании временной таблицы, что является эталоном оптимизации в 1С.
Подводя итог, можно сказать, что возможность задавать поля в секции {ВЫБРАТЬ...} для временных таблиц — это скорее следствие универсальности конструктора запросов, нежели реальная необходимость. Это не является ошибкой, но и не дает ощутимых преимуществ в большинстве сценариев. В то же время, грамотное использование секции {ГДЕ...} в тех же временных таблицах является признаком профессионального подхода к разработке на платформе 1С:Предприятие 8.3.