Как ускорить построение отчета СКД с группировкой по иерархии?

Программист IT и автоматизация бизнеса
← На главную

Рассмотрим распространенную ситуацию при разрабоке на платформе 1С. Вы делаете отчет на основании Системы Компоновки Данных (СКД), который разворачивает данные по контрагентам. Пока отчет плоский, он строится мгновенно. Однако стоит добавить к контрагенту группировку по основному менеджеру с использованием типа группировки Иерархия, как время формирования отчета увеличивается в полтора-два раза. При этом, если убрать иерархию, скорость возвращается в норму. Проанализируем причину такого поведения и разберем проверенные способы оптимизации отчета.

Почему замедляется отчет при использовании иерархии в СКД?

Штатный механизм построения иерархии в СКД архитектурно реализован таким образом, что вычисление дерева является очень трудоемкой операцией. Разберем основные причины падения производительности:

  1. Рекурсивные запросы платформы. При включении группировки «Иерархия» СКД не ограничивается одним запросом. Платформа динамически генерирует множество дополнительных SQL-запросов к СУБД, чтобы по каждому элементу получить его родителей до самого корня дерева.
  2. Агрегация в оперативной памяти. Если в отчете есть вычисляемые ресурсы (суммы, количества), процессор компоновки данных пересчитывает итоги по узлам дерева на стороне сервера приложений 1С, а не в базе данных. Перенос массива сырых данных из СУБД в оперативную память и расчет итогов в цикле часто приводит к двукратному падению скорости.
  3. Отсутствие необходимых индексов. Если реквизит, по которому строится иерархия (например, ссылка на менеджера), не проиндексирован, промежуточные выборки платформы будут вызывать полное сканирование таблиц (Table Scan) на уровне СУБД.

К сожалению, перенести этот алгоритм в один общий оптимальный запрос средствами одних лишь настроек пользовательского интерфейса СКД невозможно. Тем не менее, посмотрим на способы решения этой проблемы.

Способ 1: Отключение расчета ресурсов по иерархии

Самый простой и быстрый способ, предложенный на форуме — отключить пересчет (суммирование) ресурсов по иерархическим записям, если бизнес-логика отчета позволяет это сделать. Это снимет нагрузку с процессора компоновки данных, так как ему больше не придется выполнять ресурсоемкие вычисления итогов узлов дерева в оперативной памяти.

Способ 2: Разворачивание иерархии в плоские поля («Материализованный путь»)

Если глубина иерархии справочника ограничена и заранее известна (например, не превышает 3–4 уровней), мы рекомендуем полностью отказаться от типа группировки Иерархия в настройках вывода СКД. Вместо этого модифицируйте исходный текст запроса.

Используйте несколько левых соединений таблицы справочника самой с собой. Таким образом вы получите родительские элементы верхних уровней в отдельные плоские поля (например, Уровень1, Уровень2, Уровень3). В настройках вывода добавьте эти поля как обычные последовательные группировки. Скорость выполнения возрастет в разы, поскольку вся работа будет выполнена на стороне SQL одним запросом.

Способ 3: Использование нескольких наборов данных

Попробуем разделить получение данных на два независимых набора-запроса:

  1. В первом наборе получаем основные тяжелые данные — обороты, остатки, документы.
  2. Во втором наборе выбираем только данные иерархического справочника.

Затем перейдите на вкладку Связи наборов данных и настройте объединение. В ряде случаев такой подход радикально меняет логику генерации конечных запросов платформой. Тяжелая выборка оборотов изолируется от ресурсоемкой рекурсии построения дерева, и отчет формируется быстрее.

Способ 4: Связь набора данных с самим собой

Вместо стандартной галки «Иерархия» реализуем собственную логику рекурсии через детальные записи. Добавьте в набор данных поля Ссылка и Родитель. На вкладке Связи наборов данных настройте связь набора данных к самому себе:

В настройках структуры отчета выведите детальные записи с использованием этой связи. Этот нетиповой подход часто отрабатывает эффективнее встроенного механизма построения дерева.

Способ 5: Предварительный расчет итогов в запросе

Если итоги по узлам дерева обязательно нужны, рассчитаем их заранее на уровне СУБД, используя конструкцию языка запросов ИТОГИ ... ПО ... ТОЛЬКО ИЕРАРХИЯ. Результат выполнения такого запроса можно выгрузить в программно созданную таблицу значений и передать её в СКД как внешний набор данных (Объект).

В самом отчете группировка выводится как плоский список без галки «Иерархия». Платформа просто выведет уже готовые, предрассчитанные на уровне SQL строки, которые визуально будут выглядеть как классическое дерево с итогами, но скорость их формирования будет максимальной.

Способ 6: Оптимизация структуры метаданных (индексы)

Обязательно проанализируем структуру конфигурации. Проверьте, установлено ли свойство Индексировать у реквизита (например, у реквизита контрагента, хранящего ссылку на менеджера). Также проверьте наличие индекса у поля, выступающего в качестве родителя в самом иерархическом справочнике. Это позволит СУБД моментально находить нужные записи при обработке внутренних запросов платформы во время вычисления ветвей дерева.

← На главную