Как правильно настроить RLS в 1С и оптимизировать производительность ограничений

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

Настройка ограничений на уровне записей (RLS — Record Level Security) является одной из самых сложных и ответственных задач для разработчика 1С. Ошибка в условии не только может привести к несанкционированному доступу или, наоборот, к чрезмерным ограничениям, но и способна катастрофически замедлить работу всей системы. В данной статье мы разберем практический пример настройки условий доступа, проанализируем типичные ошибки при работе с пустыми значениями и рассмотрим современные механизмы оптимизации производительности RLS.

Различие между NULL и Пустой ссылкой в условиях RLS

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

  1. Пустая ссылка (например, ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)) — это физическое значение типа «Ссылка», которое реально хранится в полях базы данных.
  2. NULL — это специальный маркер отсутствия значения. В контексте RLS NULL чаще всего появляется при использовании левых соединений (LEFT JOIN). Если в условии ограничения вы обращаетесь к реквизиту через точку (например, Контрагент.Менеджер.Отдел), и менеджер не указан, система может вернуть NULL.

Рассмотрим ситуацию с параметрами сеанса. Если параметр сеанса &ПМЗонаДоступа не инициализирован, обращение к нему в коде RLS вызовет ошибку исполнения, а не вернет NULL. Поэтому проверка &ПМЗонаДоступа ЕСТЬ NULL часто является избыточной или ошибочной, если параметр гарантированно инициализируется в модуле сеанса.

Анализ и оптимизация условия ГДЕ

Проанализируем предложенный в обсуждении вариант условия, который призван объединить доступ по зонам и обработку исключений. Рассмотрим, как можно переписать «дикое» условие в более читаемый вид с использованием конструкции ВЫБОР КОГДА:


ГДЕ ВЫБОР 
    КОГДА Контрагент.ПМЗонаДоступа = &ПМЗонаДоступа 
          И Контрагент.ПМЗонаЗапрета <> &ПМЗонаЗапрета 
          И &ПМЗонаДоступа <> ЗНАЧЕНИЕ(Справочник.ПМЗоныДоступа.ПустаяСсылка) 
        ТОГДА ИСТИНА 
    КОГДА &ПМЗонаДоступа = ЗНАЧЕНИЕ(Справочник.ПМЗоныДоступа.ПустаяСсылка) 
          И Контрагент.ПМЗонаЗапрета <> &ПМЗонаЗапрета 
        ТОГДА ИСТИНА 
    ИНАЧЕ ЛОЖЬ 
КОНЕЦ

Хотя такая запись выглядит логичной, использование ВЫБОР КОГДА непосредственно в теле RLS-запроса создает огромную нагрузку на оптимизатор SQL-сервера. Вычисление этого выражения происходит для каждой строки таблицы, что при больших объемах данных (например, в справочнике Контрагенты или в журналах документов) приведет к значительным задержкам.

Проблема оператора ИЛИ и производительность

В первом сообщении автор использует оператор ИЛИ. Выясним причину, почему это считается плохой практикой в RLS. Когда SQL-сервер встречает OR в условии WHERE, он часто отказывается от использования индексов и переходит к полному сканированию таблицы (Table Scan). Это и есть причина того, что «о производительности можно забыть».

Рекомендация: Вместо одного сложного условия с ИЛИ, старайтесь разделять логику на несколько простых ролей. В 1С права суммируются: если пользователю разрешено чтение хотя бы по одной из ролей, он получит доступ к записи. Несколько простых запросов в разных ролях обычно работают быстрее, чем один громоздкий запрос со сложной логикой ИЛИ.

Современное решение: Производительный RLS

Начиная с версии платформы 1С:Предприятие 8.3.12, разработчикам доступен механизм «Производительного RLS». Разберем, как он меняет ситуацию. В классическом RLS платформа каждый раз при выполнении запроса динамически добавляет к нему условия ГДЕ. В производительном режиме система заранее рассчитывает ключи доступа и записывает их в специальные вспомогательные таблицы.

Преимущества производительного режима:

  1. Запросы к базе данных становятся максимально простыми — они просто соединяются с готовой таблицей прав по индексу.
  2. SQL-сервер строит стабильные планы запросов.
  3. Сложность условий (те самые ВЫБОР КОГДА) больше не влияет на скорость выборки данных пользователем, так как расчет прав происходит в фоновом режиме при изменении данных.

Использование шаблонов ограничений и БСП

Вместо того чтобы вручную прописывать сложные условия, проанализируем возможности шаблонов. В типовых конфигурациях на базе БСП (Библиотека стандартных подсистем) используются стандартные шаблоны, такие как #ПоЗначениям. Использование шаблонов позволяет:

Отладка и анализ запросов

Если вы столкнулись с тем, что динамический список начал «тормозить» после внедрения RLS, необходимо выяснить причину с помощью инструментов анализа. Выясним, во что превращается ваше условие на уровне СУБД:

Воспользуйтесь Профайлером SQL-сервера или настройте Технологический журнал (событие DBMSSQL). Вы увидите реальный текст SQL-запроса. Ищите в нем фрагменты, добавленные платформой — они будут содержать ваши условия. Обратите внимание на то, используются ли индексы (Index Seek) или происходит сканирование (Scan). Если вы видите Full Table Scan, значит, ваше условие ГДЕ (особенно с ИЛИ или ВЫБОР) не дает СУБД работать эффективно.

Привилегированный режим как способ обхода ограничений

Посмотрим на ситуацию, когда RLS мешает выполнению служебных операций. Например, при проведении документа пользователю может понадобиться информация об остатках, к которым у него нет прямого доступа. В таких случаях следует использовать УстановитьПривилегированныйРежим(Истина). Это временно отключает проверку RLS для текущего потока выполнения на сервере, что не только позволяет обойти ограничения, но и значительно ускоряет работу кода, так как условия RLS не добавляются к запросам.

Подведем итог: При проектировании RLS для «чайников с гранатой» (как иронично заметил автор темы) важно помнить, что простота — залог скорости. Избегайте NULL там, где можно обойтись пустой ссылкой, минимизируйте использование ИЛИ и ВЫБОР, а при возможности — переходите на производительный режим RLS версии 8.3.12 и выше.

← На главную