Медленная работа отчетов на Системе компоновки данных (СКД) — распространенная проблема, с которой сталкиваются разработчики 1С. Когда отчет формируется слишком долго, первым делом необходимо понять, сколько именно времени занимает этот процесс и на каком этапе происходит задержка. Разберем детально, как получить временные метки начала и окончания формирования, а также проанализируем способы оптимизации, которые помогут ускорить вывод данных.
Если отчет не имеет собственной формы и запускается стандартными средствами платформы, самый простой способ узнать время выполнения — использовать Замер производительности в конфигураторе. Проанализируем, как это сделать правильно:
В открывшемся окне мы увидим детальную таблицу. Нас интересует суммарное время выполнения процедур. Хотя для чистого СКД без программного кода мы увидим лишь время работы внутренних функций платформы, это даст понимание общего интервала ожидания. Если провести штатную отладку на сервере невозможно, для анализа отчетов в реальных условиях подойдет расширение для отладки СКД и запросов под сеансом пользователя.
Для более точного контроля, особенно если мы хотим выводить время выполнения пользователю, рассмотрим вариант программного вызова формирования СКД. Это потребует создания формы отчета и переопределения действия кнопки «Сформировать». Выясним, как реализовать замер времени с точностью до миллисекунд.
В модуле формы отчета пропишем следующий алгоритм:
Процедура ДействиеСформировать(Кнопка)
// Фиксируем время начала
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
// Очищаем результат
Результат.Очистить();
// Стандартное программное формирование
СкомпоноватьРезультат(Результат);
// Фиксируем время окончания
ВремяКонца = ТекущаяУниверсальнаяДатаВМиллисекундах();
// Рассчитываем интервал в секундах
Длительность = (ВремяКонца - ВремяНачала) / 1000;
Сообщить("Отчет сформирован за " + Формат(Длительность, "ЧЦ=10; ЧДЦ=3") + " сек.");
КонецПроцедуры
Использование функции ТекущаяУниверсальнаяДатаВМиллисекундах() предпочтительнее, чем ТекущаяДата(), так как она позволяет зафиксировать даже доли секунды, что критично при отладке быстрых, но часто вызываемых отчетов.
Зачастую отчет тормозит не на этапе выполнения запроса к базе данных, а на этапе компоновки макета или вывода данных в табличный документ. Чтобы понять, где именно «узкое место», разберем по шагам процесс программного вывода СКД:
// 1. Инициализация схемы и настроек
СхемаКД = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// 2. Компоновка макета (создание структуры)
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКД, Настройки, ДанныеРасшифровки);
Сообщить("Компоновка макета: " + (ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа) + " мс.");
// 3. Выполнение запроса и инициализация процессора
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
Сообщить("Инициализация процессора (запрос): " + (ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа) + " мс.");
// 4. Вывод в табличный документ
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Сообщить("Вывод результата: " + (ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа) + " мс.");
Важный момент: если основное время тратится на «Вывод результата», значит, проблема в огромном количестве строк, сложной иерархии или избыточном условном оформлении. Если на «Инициализацию процессора» — проблема в самом SQL-запросе — решается через инструмент анализа производительности и оптимизации SQL-запросов 1С.
Для профессиональной диагностики рекомендуется использовать внешние обработки, такие как «Консоль системы компоновки данных» (входит в состав инструментов разработчика) — для этого подойдёт внешняя консоль СКД для анализа и оптимизации. Посмотрим, какие преимущества это дает:
Замер времени — это лишь диагностика. Рассмотрим основные причины деградации производительности и способы их устранения:
1. Связи наборов данных. Если вы используете несколько наборов данных (например, запрос и объект) и связываете их на вкладке «Связи наборов данных», 1С может выполнять отдельный запрос к БД для каждой строки основного набора. Это классическая проблема N+1. Решение: по возможности объединяйте данные внутри одного запроса с помощью ЛЕВОЕ СОЕДИНЕНИЕ.
2. Параметры виртуальных таблиц. Убедитесь, что отборы по датам, организациям и другим измерениям передаются непосредственно в параметры виртуальных таблиц (например, в РегистрНакопления.Остатки(&Период, &Условие)). Если отбор накладывается просто в тексте запроса через ГДЕ или в настройках СКД без связи с параметрами, система сначала выберет все записи регистра, а затем отфильтрует их, что крайне медленно.
3. Вычисляемые поля и функции. Использование функций общих модулей в вычисляемых полях СКД заставляет систему переключать контекст с SQL-сервера на сервер приложений 1С для каждой строки. Рассмотрим пример: если в отчете 100 000 строк и в каждой вызывается функция ОбщегоНазначения.ПолучитьДанные(), отчет будет «висеть». Решение: старайтесь получать все необходимые данные в основном запросе через соединения таблиц.
4. Роли полей и индексация. Проверьте, чтобы в схеме компоновки были правильно расставлены роли для полей периодов и измерений. Также убедитесь, что поля, по которым строятся связи, проиндексированы в базе данных. Не забывайте про флаг «Обязательное» в настройках связей, если это логически допустимо — это помогает оптимизатору СКД строить более эффективные планы запросов.
5. Избыточность данных. Проанализируйте, не включено ли у вас «Автозаполнение» в запросе. Если оно включено, СКД может тянуть из базы поля, которые не используются в текущем варианте отчета, но присутствуют в доступных полях. Отключение автозаполнения и ручной выбор только нужных полей может существенно сократить объем передаваемых данных.
Для эффективного решения проблемы долгой работы отчета мы должны сначала локализовать проблему с помощью ТекущаяУниверсальнаяДатаВМиллисекундах() или замера производительности, а затем последовательно оптимизировать структуру запроса, избегая типовых ошибок компоновки данных. Помните, что лучший отчет — это тот, который предоставляет пользователю только необходимые данные в максимально агрегированном виде. Для комплексного анализа структуры компоновки и планов запросов без изменения конфигурации можно использовать управляемую консоль отчетов и запросов.