При разработке произвольных схем компоновки данных (СКД), в частности для формирования динамических или регламентных сегментов партнеров в «1С:Управление торговлей 11», разработчики нередко сталкиваются с ситуацией: в консоли запросов запрос с соединением или вложенным запросом отрабатывает корректно, а при программном выполнении СКД часть выборки с итогами просто пропадает.
Разберем детально, почему компоновщик отсекает секции запроса и какие инструменты позволяют управлять этим поведением.
Проанализируем механизм работы платформы при компоновке запроса. Генератор СКД выполняет автоматическую оптимизацию текста запроса перед отправкой в СУБД:
Партнер). Если данные из регистра накопления (выручка, себестоимость) использовались во вложенном запросе только для расчета условий, но не были зафиксированы как обязательные, платформа исключает соединение.Рассмотрим самый простой способ заставить СКД гарантированно выполнять расчет вложенных данных:
Данная настройка сообщает процессору компоновки данных, что поле должно присутствовать в результирующем запросе независимо от того, выбрал ли его пользователь в текущих настройках отчета или варианта.
Посмотрим, как запретить оптимизатору исключать соединения на уровне самого запроса СКД:
В тексте запроса это убирает фигурные скобки {} вокруг секции ЛЕВОЕ СОЕДИНЕНИЕ, делая его безусловным для СУБД при любых вариантах настроек компоновщика.
Разберем более надежный с точки зрения производительности и оптимизации подход. Вместо глубоких вложенных запросов в секции ИЗ рекомендуется использовать пакетные запросы с сохранением промежуточных итогов во временную таблицу:
ВЫБРАТЬ
ВыручкаИСебестоимость.АналитикаУчетаПоНоменклатуре.Партнер КАК Партнер,
СУММА(ВыручкаИСебестоимость.СуммаВыручки) КАК СуммаВыручкиИтог
ПОМЕСТИТЬ ВТ_ИтогиПродаж
ИЗ
РегистрНакопления.ВыручкаИСебестоимостьПродаж КАК ВыручкаИСебестоимость
СГРУППИРОВАТЬ ПО
ВыручкаИСебестоимость.АналитикаУчетаПоНоменклатуре.Партнер
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
СпрПартнеры.Ссылка КАК Партнер,
ЕСТЬNULL(ВТ_ИтогиПродаж.СуммаВыручкиИтог, 0) КАК СуммаВыручки
ИЗ
Справочник.Партнеры КАК СпрПартнеры
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ИтогиПродаж КАК ВТ_ИтогиПродаж
ПО СпрПартнеры.Ссылка = ВТ_ИтогиПродаж.Партнер
Использование временных таблиц упрощает анализ структуры для СКД, делает план выполнения в СУБД более предсказуемым и гарантирует корректную предварительную агрегацию данных до основного соединения.
Проанализируем альтернативную архитектуру схемы, исключающую сложные соединения внутри одного запроса:
Справочник.Партнеры.Партнеры с приемником Продажи по полю Партнер.В этом случае объединение данных и расчет итогов берет на себя процессор компоновки, что полностью предотвращает дублирование строк и некорректное исключение условий при программном формировании отчетов и сегментов.