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

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

В практике разработки на платформе 1С нередко возникает ситуация, когда сам запрос отчета в консоли запросов выполняется за считанные секунды или минуты, но при формировании отчета через Систему компоновки данных (СКД) процесс замирает на 0% и выполняется очень долго (иногда часами). Проблема может проявляться как после обновления платформы или переустановки сервера, так и при изменении пользовательских настроек отчета.

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

Шаг 1. Локализация проблемы с помощью замера производительности

Первым делом необходимо точно определить, на каком этапе система теряет время: на стороне СУБД при выполнении запроса или на этапе работы процессора вывода компоновки данных на сервере 1С.

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

  1. Включим отладку на сервере 1С (параметр запуска службы -debug).
  2. Запустим конфигуратор, подключимся к сеансу и откроем окно замера производительности.
  3. Сформируем проблемный отчет в пользовательском режиме.
  4. Остановим замер и проанализируем дерево вызовов.

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

Причина 1. Избыточное количество элементов и пользовательские группировки

Одна из самых частых причин зависания вывода — создание огромного количества строк и колонок из-за некорректных настроек группировок. Если пользователь случайно задал группировку по детальным записям или добавил посекундную группировку в кросс-таблице, итоговый результат может содержать сотни тысяч мелких ячеек.

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

Причина 2. Вычисление представлений ссылочных полей

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

Чтобы избежать этой проблемы, разберем возможные решения:

  1. В схеме компоновки данных на вкладке Поля для ссылочных полей явно укажем Выражение представления, например: Ссылка.Наименование или Ссылка.Представление. Это позволит получать строковое значение прямо из запроса без дополнительной обработки платформой.
  2. Если представление ссылки не требуется для отображения, следует исключить лишние реквизиты из поля Выбранные поля в настройках отчета.

Причина 3. Вычислимые поля и функции в ресурсах

Использование в схеме СКД вычислимых полей, обращающихся к экспортным функциям общих модулей с серверными вызовами, резко снижает скорость формирования отчета. Если такая функция вызывается для каждой строки результата (например, 100 000 раз), время вывода вырастет экспоненциально.

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

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

Причина 4. Влияние операционной системы и настроек СУБД

Если зависание отчетов началось строго после переустановки Windows Server или SQL Server при неизменном коде отчета, разберем системные факторы, влияющие на скорость вывода СКД:

  1. Схема питания Windows Server: По умолчанию в операционной системе может быть установлен план электропитания Balanced (Сбалансированный). При однопоточных вычислениях СКД процессор не поднимает частоту до максимума. Переключение плана на High Performance (Высокая производительность) устраняет эту проблему.
  2. Исключения антивируса: Процессор вывода СКД активно использует временные файлы во вложенных каталогах профиля службы 1С. В исключения сканирования антивируса необходимо добавить папки AppData\Local\Temp, каталоги временных файлов 1С, а также процессы rphost.exe и sqlservr.exe.
  3. Настройки TempDB: При компоновке сложных отчетов платформа создает во временной базе SQL Server промежуточные таблицы. Убедитесь, что база tempdb имеет несколько файлов данных одинакового размера с достаточным шагом авторасширения.

Шаг 2. Программная отладка поэлементного вывода

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


СхемаКомпоновки = ПолучитьМакет("СхемаКомпоновкиДанных");
Настройки = СхемаКомпоновки.НастройкиПоУмолчанию;

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, Настройки);

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

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

ПроцессорВывода.НачатьВывод();

Счетчик = 0;
Пока Истина Цикл
    ЭлементРезультата = ПроцессорКомпоновки.Следующий();
    Если ЭлементРезультата = Неопределено Тогда
        Прервать;
    КонецЕсли;
    
    ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
    
    Счетчик = Счетчик + 1;
    Если Счетчик % 10000 = 0 Тогда
        Сообщить("Выведено элементов: " + Формат(Счетчик, "ЧГ=0"));
    КонецЕсли;
КонецЦикл;

ПроцессорВывода.ЗакончитьВывод();

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

Итоги и рекомендации

Если отчет на СКД выполняется быстро в консоли запросов, но замирает при выводе пользователю:

  1. Проверьте пользовательские настройки группировок на предмет избыточной детальности.
  2. Убедитесь, что в схеме отчета не используются вызовы функций общих модулей в вычислимых полях.
  3. Задайте выражения представлений для ссылочных полей вручную.
  4. Проверьте схему электропитания сервера и исключения антивируса для временных папок.
← На главную