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