Почему СКД долго выводит результат в диаграмму и как ускорить формирование отчета

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Анализ механизма выполнения отчета в СКД

Проанализируем типовой программный код формирования отчета, на котором чаще всего фиксируется задержка:


МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеНаборы);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);

Замер производительности в подобных сценариях показывает, что вызов КомпоновщикМакета.Выполнить отрабатывает мгновенно (сотые доли секунды), а строка ПроцессорВывода.Вывести(...) выполняется от 20 до 50 секунд и более. Выясним причину такого поведения:

  1. Реальное выполнение запроса к СУБД: метод КомпоновщикМакета.Выполнить лишь формирует внутренний макет и план исполнения, не обращаясь к базе данных. Сам запрос к СУБД и получение выборки строк происходят именно внутри вызова ПроцессорВывода.Вывести (или при первом вызове ПроцессорКомпоновкиДанных.Следующий()).
  2. Модификация запроса компоновщиком: СКД перестраивает исходный текст запроса в зависимости от выбранных полей, группировок и отборов. Реальный запрос к СУБД хранится в свойстве МакетКомпоновки.НаборыДанных[0].Запрос. Если в настройках добавлены поля через точку от ссылочных реквизитов, СКД добавит неявные левые соединения, что может резко замедлить выборку.
  3. Специфика построения диаграмм: диаграмма в СКД оперирует декартовым произведением точек и серий (матрица «Точки × Серии»). При большом количестве уникальных значений платформа выполняет ресурсоемкую агрегацию и построение графического объекта в оперативной памяти сервера 1С.
  4. Постобработка и вычисляемые поля: если выражения ресурсов, вычисляемых полей или представлений рассчитываются средствами СКД, эти вычисления выполняются в цикле для каждой ячейки результирующей матрицы, создавая колоссальную нагрузку на процессор.

Способы оптимизации и ускорения вывода

Рассмотрим практические рекомендации, которые позволяют сократить время построения диаграммы в разы.

1. Перенос всех расчетов и выражений в запрос

Основное правило высокой производительности СКД — переносить все возможные вычисления из вкладок «Вычисляемые поля» и «Ресурсы» непосредственно в текст запроса на языке 1С. Посмотрим, что именно следует перенести:

  1. Использовать операторы ВЫБОР КОГДА ... ТОГДА ... КОНЕЦ в запросе вместо выражений СКД.
  2. Выполнять предварительную группировку данных в запросе (СГРУППИРОВАТЬ ПО), чтобы в процессор компоновки передавался минимально необходимый объем строк.
  3. Получать представления объектов через ПРЕДСТАВЛЕНИЕ() или связыванием реквизитов (например, Код, Наименование) напрямую в запросе, исключая неявные разыменования ссылок через точку на этапе обхода строк процессором вывода.

2. Оптимизация структуры диаграммы и дополнения периодов

Проанализируем настройки группировок диаграммы. Если в точках используется поле даты или периода, по умолчанию СКД может применять автоматическое дополнение периода. При мелком шаге (например, дни за целый год) генерируется огромное количество пустых точек, что приводит к раздуванию матрицы диаграммы.

Для устранения этой проблемы проверим настройки группировки периода:

  1. Отключим автоматическое дополнение периода в свойствах группировки диаграммы, если отображение пустых интервалов не требуется.
  2. Укрупним периодичность (например, вывод по месяцам или неделям вместо дней).
  3. Установим ограничение количества серий (вывод первых N наиболее значимых значений), чтобы исключить построение сотен мелких линий или секторов.

3. Программный вывод через Таблицу Значений

Если диаграмма содержит сложную динамическую логику настройки серий и точек, стандартный ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент создает избыточные накладные расходы на сведение иерархий. В таких случаях эффективнее выгрузить скомпонованный результат в коллекцию значений и заполнить диаграмму на форме вручную.

Разберем пример реализации вывода через ТаблицаЗначений:


ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеНаборы);

ТаблицаРезультата = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ТаблицаРезультата);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);

// Заполнение диаграммы на форме по компактной таблице
Диаграмма.Обновление(Ложь);
Диаграмма.Очистить();
Для Каждого Стр Из ТаблицаРезультата Цикл
    Точка = Диаграмма.УстановитьТочку(Стр.Точка);
    Серия = Диаграмма.УстановитьСерию(Стр.Серия);
    Диаграмма.УстановитьЗначение(Точка, Серия, Стр.ЗначениеРесурса);
КонецЦикла;
Диаграмма.Обновление(Истина);

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

← На главную