В практике разработчика 1С часто встречается ситуация, когда типовой или незначительно доработанный отчет, годами работавший за секунды, внезапно начинает «тормозить». Особенно это заметно на отчете «Карточка счета», который является одним из самых востребованных в 1С:Бухгалтерии. Рассмотрим ситуацию, когда база небольшая (около 7 Гб на SQL), значительных обновлений не было, но время формирования выросло с 2 до 10 секунд. Выясним причину такого поведения и разберем системные методы решения проблемы.
Когда мы сталкиваемся с деградацией производительности на SQL-версии, первым делом мы проверяем состояние базы данных. Проанализируем стандартный список действий, которые обычно выполняет администратор или программист:
Если все вышеперечисленное выполнено, а копия базы на другом сервере ведет себя так же медленно, мы понимаем: проблема в данных или коде, а не в «железе» или настройках SQL-сервера. Разберем, как локализовать проблему с помощью инструментов отладки.
Проанализируем результаты трассировки в SQL Profiler. В рассматриваемом случае количество строк в профайлере при запуске отчета выросло с 96 (в быстрой копии) до 14 803 (в медленной). При этом длительных запросов нет — есть «каша» из тысяч мелких обращений.
Такое поведение системы характерно для двух ситуаций:
Важно помнить, что в современных конфигурациях отчеты формируются в фоновых заданиях. С точки зрения платформы 1С, каждое фоновое задание — это отдельный сеанс со всеми вытекающими последствиями.
Выясним причину замедления. Как показывает практика, корень проблемы часто скрыт в общем модуле МодульСеанса, а именно в процедуре УстановкаПараметровСеанса. Рассмотрим механизм работы этого события.
При запуске любого сеанса (включая фоновое задание для отчета или динамического списка) система вызывает эту процедуру. Если в нее был добавлен «тяжелый» код для инициализации параметров RLS, этот код будет выполняться каждый раз при нажатии кнопки «Сформировать».
Пример кода, который может добавить 8 секунд к любому действию:
Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
// Допустим, мы вычисляем массив разрешенных организаций для RLS
// Этот запрос выполняется 8 секунд
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Организации ГДЕ ...";
ПараметрыСеанса.ДоступныеОрганизации = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
КонецПроцедуры
Для пользователя, который заходит в программу раз в день, задержка в 8 секунд незаметна. Но для фонового задания отчета это критично. Рассмотрим способы оптимизации этого узкого места.
Проанализируем массив ТребуемыеПараметры, который передается в процедуру. Платформа 1С сама сообщает, какой именно параметр ей нужен в данный момент. Не нужно заполнять все параметры сразу, если системе нужен только один.
Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
Если ТребуемыеПараметры = Неопределено Тогда
// Первый вход пользователя - инициализируем минимум
Возврат;
КонецЕсли;
Для Каждого ИмяПараметра Из ТребуемыеПараметры Цикл
Если ИмяПараметра = "ДоступныеОрганизации" Тогда
// Выполняем расчет только тогда, когда система его запросила
ПараметрыСеанса.ДоступныеОрганизации = ПолучитьСписокДоступныхОрганизаций();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Если вычисление параметра неизбежно занимает много времени, следует рассмотреть вариант хранения этих данных в регистре сведений. В этом случае в модуле сеанса мы будем выполнять простой запрос к уже готовой таблице вместо сложных вычислений.
Также важно различать типы сеансов. Проанализируем, как определить, что код выполняется в фоновом задании. Существует два подхода:
ИмяПриложения:
ПолучитьТекущийСеансИнформационнойБазы().ИмяПриложения = "BackgroundJob"
ПолучитьФоновоеЗадание():
ПолучитьТекущийСеансИнформационнойБазы().ПолучитьФоновоеЗадание() <> Неопределено
Важное замечание по производительности: Как показывают замеры, обращение к методу ПолучитьФоновоеЗадание() работает в 10–100 раз медленнее, чем проверка свойства ИмяПриложения, так как оно требует обращения к менеджеру кластера. В критичных к скорости участках кода, таких как модуль сеанса, рекомендуется использовать проверку строки "BackgroundJob".
Проанализируем ситуацию далее: эта же проблема будет проявляться и при поиске в динамических списках, если они используют RLS, завязанный на параметры сеанса. Каждый раз, когда система решает пересчитать права или обновить данные в фоне, она будет «натыкаться» на задержку в модуле сеанса.
Разберем рекомендации по системному исправлению:
МодульСеанса или добавление новых правил RLS.Таким образом, мы выяснили, что причина замедления отчета «Карточка счета» часто кроется не в самом запросе отчета, а в «обвязке» системы. Оптимизация инициализации параметров сеанса и правильное использование кэширования позволяют вернуть скорость работы отчета к исходным показателям (менее 2 секунд).