При проектировании прав доступа в системе «1С:Предприятие» разработчики часто сталкиваются с неочевидным поведением платформы. Типичный сценарий: у пользователя настроено ограничение доступа на уровне записей (RLS) на определенное измерение регистра. Чтобы ускорить выполнение критически важного запроса, разработчик переносит его в привилегированный общий модуль и убирает ключевое слово РАЗРЕШЕННЫЕ.
Логика подсказывает, что в привилегированном режиме проверка прав полностью игнорируется, и запрос должен отрабатывать с максимально возможной скоростью — точно так же, как у администратора без RLS. Однако на практике (особенно в файловом режиме работы базы данных) замеры производительности показывают, что запрос у «ограниченного» пользователя все равно выполняется в несколько раз медленнее. Разберем по шагам физику этого процесса, выясним причины такого поведения платформы и найдем способы оптимизации.
Существует распространенное заблуждение, что привилегированный режим полностью отключает все механизмы RLS на этапе подготовки запроса. На самом деле это происходит не совсем так. Проанализируем цепочку действий, выполняемых платформой при вызове метода Запрос.Выполнить():
.1CD), платформа выполняет синтаксический анализ и разбор метаданных. В этот процесс всегда вовлечен анализ контекста безопасности текущего пользователя. Слой SDBL проверяет роли пользователя, чтобы определить структуру и необходимость модификации запроса. Логика «проверить, настроен ли RLS для этого пользователя по метаданным, сопоставить его роли и принять решение о пропуске проверок ввиду привилегированного режима» выполняется на процессоре сервера 1С каждый раз. Это создает дополнительные накладные расходы (overhead).Почему эта разница в скорости критически заметна именно в файловом варианте работы и практически незаметна в клиент-серверном? Рассмотрим особенности архитектуры файлового движка:
Запрос.Выполнить() — до 70–80%. Отсюда мы и получаем трехкратную разницу в замерах (например, 0.025 секунды без RLS против 0.08 секунды с включенным RLS).Рассмотрим интересную особенность поведения платформы при изменении режима совместимости. При проведении тестов в файловой базе были получены следующие результаты:
Выясним причину такого «замедления» работы запроса без ограничений в режиме 8.3:
Если в вашем прикладном решении разница в скорости критична для пользователей, а использовать RLS необходимо, рекомендуем применить следующие подходы:
Для баз данных объемом более 10 Гб с активным использованием механизмов разграничения прав доступа на уровне записей файловый режим перестает быть оптимальным выбором. Переход на полноценную СУБД (например, PostgreSQL) решает проблему за счет эффективного кэширования планов запросов на стороне СУБД и распараллеливания процессов обработки данных.
В современных конфигурациях стандартный шаблон RLS (который динамически строит тяжелые левые соединения при каждом запросе) рекомендуется заменить на производительный режим RLS, предоставляемый Библиотекой Стандартных Подсистем (БСП). Рассмотрим его принцип работы:
Убедитесь, что логика получения данных действительно изолирована в общем модуле с установленными свойствами «Сервер» и «Привилегированный». Пример вызова процедуры получения остатков без использования избыточных проверок:
// Код внутри общего привилегированного модуля "упУправлениеОстатками"
Функция ПолучитьОстаткиТоваровПривилегированно(ВыбСклад) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
| ТоварыНаСкладахОстатки.В НаличииОстаток КАК Количество
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад = &ВыбСклад) КАК ТоварыНаСкладахОстатки";
Запрос.УстановитьПараметр("ВыбСклад", ВыбСклад);
// В привилегированном режиме ключевое слово РАЗРЕШЕННЫЕ не требуется
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Использование этого метода гарантирует, что на стороне СУБД запрос выполнится по полной таблице без наложения дополнительных условий RLS, а небольшая задержка на этапе SDBL-компиляции в файловом режиме останется фиксированной и прогнозируемой.