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