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

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Переход от вложенных запросов к временным таблицам

Проанализируем типичную ошибку в структуре запроса. Использование вложенных запросов (когда один ВЫБРАТЬ находится внутри другого) — это основной фактор замедления. СУБД (например, MS SQL Server) сложно построить оптимальный план выполнения для "матрешки" из запросов, особенно если их глубина велика.

Рассмотрим, как следует преобразовать запрос. Вместо конструкции:


ВЫБРАТЬ
    ПланФакт.Контрагент,
    ПланФакт.Сумма
ИЗ
    (ВЫБРАТЬ ... ИЗ РегистрНакопления.Продажи.Обороты(...) КАК Продажи) КАК ПланФакт

Мы должны использовать временные таблицы.

  1. Выбираем первичные данные во временную таблицу.
  2. Обязательно индексируем поля, по которым в дальнейшем будет происходить соединение или фильтрация.
  3. Выбираем данные из временной таблицы в основной запрос.

Пример оптимизированной структуры:


ВЫБРАТЬ
    ПродажиОбороты.ДоговорКонтрагента.Владелец КАК Контрагент,
    ПродажиОбороты.СтоимостьОборот КАК Сумма
ПОМЕСТИТЬ ВТ_Продажи
ИЗ
    РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ПродажиОбороты;

ИНДЕКСИРОВАТЬ ПО
    Контрагент;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Продажи.Контрагент,
    СУММА(ВТ_Продажи.Сумма) КАК Сумма
ИЗ
    ВТ_Продажи КАК ВТ_Продажи
СГРУППИРОВАТЬ ПО
    ВТ_Продажи.Контрагент

Как показывает практика, такая замена может ускорить выполнение запроса в десятки и даже сотни раз за счет эффективного использования индексов и предсказуемого плана выполнения SQL.

Оптимизация работы с иерархией и родителями

Часто в отчетах требуется определить "уровень" объекта или найти его родителя на определенной глубине (например, бренд верхнего уровня). Использование конструкций вида Номенклатура.Бренд.Родитель.Родитель крайне неэффективно, так как порождает цепочку левых соединений (Left Join) в SQL-запросе для каждой строки данных.

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

Если же необходимо ограничить выборку конкретными узлами иерархии, используйте оператор В ИЕРАРХИИ в параметрах виртуальных таблиц или в секции ГДЕ, предварительно подготовив список нужных родителей во временной таблице.

Использование параметров виртуальных таблиц

Выясним причину долгого получения данных из регистров. Огромная ошибка — не указывать параметры (период, условия) непосредственно в виртуальной таблице, а накладывать их позже в секции ГДЕ.

Неправильно:
РегистрНакопления.Продажи.Обороты() КАК Продажи ГДЕ Продажи.Период МЕЖДУ &Дата1 И &Дата2

Правильно:
РегистрНакопления.Продажи.Обороты(&Дата1, &Дата2, , ) КАК Продажи

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

Настройка вывода и параметров ресурсов

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

  1. Отключение расшифровки: В свойствах отчета или программно можно установить параметр ПараметрыВывода.ВыводитьРасшифровку = Ложь. Это существенно экономит оперативную память, так как системе не нужно хранить информацию о связи каждой ячейки с объектами базы данных.
  2. Ограничение расчета ресурсов: В СКД на закладке "Ресурсы" проверьте колонку "Рассчитывать по...". Если у вас есть тяжелые вычисляемые поля (например, процент выполнения плана), не считайте их по детальным записям, если пользователю нужны только итоги по группам.
  3. Макеты оформления: Использование сложных макетов (цвета, рамки, шрифты) замедляет отрисовку. Для экстремально больших отчетов рекомендуем использовать макет "Без оформления" или "Минимальный".

Технические аспекты серверной части (rphost)

Если вы получаете ошибку "Недостаточно памяти", важно понимать, как работает сервер 1С. В 32-битных версиях сервера рабочий процесс rphost ограничен адресным пространством в 4 Гб (на практике — около 3 Гб). При формировании гигантского отчета СКД пытается собрать все данные в памяти этого процесса.

Рассмотрим способы решения этой проблемы:

Дополнительные приемы оптимизации текста запроса

Посмотрим на пример того, как избежать неявных вызовов к базе данных. При обращении через точку к полям ссылочных объектов (например, Продажи.Контрагент.Наименование), система делает неявное соединение.

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

Также стоит избегать функций от параметров внутри запроса. Например, вместо КОНЕЦПЕРИОДА(&ДатаКон, МЕСЯЦ) лучше передать в запрос уже готовую и вычисленную дату через программную установку параметров.

Соблюдение этих правил позволит вам создавать быстрые и стабильные отчеты даже на самых нагруженных информационных базах.

← На главную