Почему внешний отчет на СКД долго формируется при включении RLS и как это исправить?

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

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

Причина замедления: как работает RLS «под капотом»

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

Если ваш отчет содержит 13 объединенных запросов (оператор ОБЪЕДИНИТЬ ВСЕ), платформа вынуждена применить шаблоны ограничений 13 раз — по одному разу для каждой части объединения. В итоге итоговый SQL-запрос, который отправляется к базе данных, разрастается до гигантских размеров. Файловая СУБД крайне неэффективно строит планы выполнения для таких перегруженных конструкций, что приводит к колоссальным задержкам.

Решение №1: Переход на клиент-серверный вариант работы

Как показывает практика и опыт участников обсуждения, самым быстрым и эффективным способом решения проблемы является перевод базы данных из файлового режима в клиент-серверный (с использованием MS SQL Server, PostgreSQL или других СУБД). Рассмотрим, почему это помогает:

  1. Оптимизация планов запросов: Полноценные SQL-серверы обладают гораздо более мощными оптимизаторами. Они способны «переварить» сложные вложенные запросы, порожденные механизмом RLS, и найти кратчайший путь к данным.
  2. Параллельная обработка: Сервер приложений 1С и сервер СУБД могут выполнять часть операций параллельно, что невозможно в файловом режиме, где операции чтения/записи блокируют базу на более низком уровне.
  3. Эффективная работа с памятью: При выполнении объединения 13 таблиц в файловом режиме платформа создает огромные временные файлы на диске пользователя, что замедляет работу. Сервер БД делает это в оперативной памяти или оптимизированных временных таблицах.

В рассматриваемом случае переход на клиент-сервер позволил сократить время формирования отчета с 30 минут до 20 секунд без изменения программного кода.

Решение №2: Оптимизация структуры запроса (уход от 13 объединений)

Если переход на клиент-сервер невозможен, или если отчет продолжает работать медленно даже там, проанализируем структуру запроса. Использование 13 ОБЪЕДИНИТЬ ВСЕ — это сигнал о том, что данные собираются из множества разнородных источников. Рассмотрим, как это можно оптимизировать:

  1. Использование временных таблиц: Вместо одного гигантского запроса с объединениями, разделим получение данных на этапы. Сначала соберем данные из каждого источника в одну или несколько временных таблиц.
  2. Объединение во временных таблицах: Когда данные уже находятся в одной временной таблице, финальный запрос к ней будет содержать проверку RLS только один раз, а не 13. Это значительно снизит нагрузку на систему.

Решение №3: Использование привилегированного режима

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

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


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

Важно: При использовании этого метода данные будут получены без учета RLS, что обеспечит максимальную скорость. Однако вы должны быть уверены, что это не нарушает политику безопасности компании.

Решение №4: Настройка «Производительного режима» RLS

В современных версиях платформы (8.3.16+) существует два режима работы ограничений доступа. Проверим настройки в конфигураторе:

Чтобы «Производительный режим» действительно ускорил работу, необходимо убедиться, что:

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

В файловом варианте даже «Производительный режим» может не давать существенного прироста, если 13 объединенных запросов обращаются к разным типам объектов (например, 5 справочников и 8 регистров), так как системе все равно нужно сопоставлять ключи доступа для каждого типа объекта.

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

Посмотрим на дополнительные факторы, которые могут влиять на скорость:

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

← На главную