При разработке отчетов на Системе компоновки данных (СКД) часто возникает дилемма: объединить все таблицы в одном большом запросе или использовать механизм Связи наборов данных на соответствующей закладке конструктора СКД. На первый взгляд кажется, что один запрос всегда лучше, так как он выполняется целиком на стороне СУБД. Однако существуют специфические задачи, где использование связей наборов данных не только удобнее, но и является единственным верным архитектурным решением. Рассмотрим эти случаи подробнее, проанализируем их механику и выясним, когда и какой инструмент стоит применять.
Одной из самых мощных возможностей СКД является построение иерархии. В обычном запросе через предложение ИТОГИ ПО ... ИЕРАРХИЯ мы можем получить иерархию только для справочников или планов видов характеристик, используя их предопределенные родителе-дочерние связи. Но что делать, если нужно построить дерево по данным, которые сами по себе не являются иерархическими? Например, по числовым кодам или сложным аналитическим разрезам.
Рассмотрим ситуацию, когда нам нужно связать таблицу «саму с собой» для формирования дерева произвольной глубины. В обычном запросе количество уровней вложенности будет ограничено количеством прописанных соединений (JOIN). В СКД же через связи наборов данных мы можем указать поле Родитель, которое будет ссылаться на Идентификатор этого же набора данных. Система автоматически выполнит рекурсивные запросы (так называемый «запрос в цикле») и построит дерево любой глубины. Это единственный надежный способ реализовать сложную иерархию без заранее известного количества уровней.
Часто бизнес-задача требует вывести в отчет дополнительные реквизиты (характеристики) номенклатуры или контрагентов в виде отдельных колонок. Проблема в том, что количество этих свойств заранее неизвестно и может меняться пользователями в режиме 1С:Предприятие.
Если мы решим делать это в одном запросе, нам придется либо жестко прописывать ЛЕВОЕ СОЕДИНЕНИЕ для каждого свойства, либо динамически формировать текст запроса в коде, что неудобно и трудно поддерживать. Проанализируем, как это решается через связи наборов данных:
НаборДанных1 (основные данные: Номенклатура, Количество).НаборДанных2 (запрос к регистру сведений дополнительных сведений).Номенклатура.Свойство из второго набора.В этом случае СКД сама «развернет» данные в кросс-таблицу. При этом система выполнит соединение только для тех данных, которые попали в итоговую выборку после применения всех фильтров пользователя, что может быть эффективнее огромного запроса с сотней соединений.
Рассмотрим ситуацию, когда второй набор данных является запросом к виртуальной таблице, например, ОстаткиИОбороты, и нам нужно передать в параметры этой таблицы данные из первого набора (например, дату или конкретный объект). В обычном запросе соединение с виртуальной таблицей часто приводит к тому, что СУБД сначала вычисляет итоги по всей таблице, а только потом выполняет JOIN, что катастрофически сказывается на производительности.
При использовании связей наборов данных в СКД мы можем настроить передачу параметров. Система работает следующим образом: она получает результат из первого набора, собирает уникальные значения полей связи и передает их во второй набор как массив параметров. Это позволяет виртуальной таблице работать только с нужным подмножеством данных. Разберем пример настройки связи:
// Поле источника: Номенклатура
// Поле приемника: Номенклатура
// Параметр: &НоменклатураДляОстатков
В этом случае второй запрос будет выполнен эффективно, так как он получит ограниченный список объектов через параметр.
Выясним причину, по которой иногда невозможно использовать только один запрос. Это происходит, когда часть данных берется из базы (через НаборДанныхЗапрос), а часть — из внешнего источника, например, из таблицы значений, сформированной программно (НаборДанныхОбъект).
Сценарий использования: Мы рассчитали сложные бонусы менеджеров в специальном алгоритме и поместили их в таблицу значений. Теперь нам нужно вывести их рядом с данными о продажах из регистра. Единственный способ «подклеить» эти расчеты к отчету без записи их в промежуточные таблицы базы данных — это связать набор-запрос и набор-объект на закладке Связи наборов данных.
Разберем важный технический нюанс: место выполнения. Соединение в запросе выполняется на стороне СУБД. Связь наборов в СКД выполняется на Сервере приложений 1С. Если запросы очень сложные и нагружают SQL-сервер, иногда имеет смысл разделить их на два более простых и доверить их «склейку» серверу 1С. Это также упрощает отладку: вы можете проверить каждый запрос по отдельности, убедиться в корректности их работы, а затем настроить связь.
Важные моменты при настройке связей:
JOIN внутри запроса.Проанализировав ситуацию, можно сделать вывод: если вам нужно просто соединить две физические таблицы БД и данных немного — делайте это в одном запросе. Это быстрее и привычнее для СУБД. Однако, если ваша задача включает:
Тогда использование Связей наборов данных в СКД является наиболее профессиональным и эффективным подходом.