Почему документы в 1С:ERP открываются очень долго под правами с RLS и как это исправить?

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

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

В данной статье мы подробно разберем, почему возникают такие задержки, как платформа 1С взаимодействует с SQL-сервером при использовании RLS и какие шаги необходимо предпринять для исправления ситуации.

Анализируем причину: как RLS влияет на SQL-запросы

Когда мы работаем под полными правами, платформа отправляет к СУБД «чистый» запрос. Однако, как только в дело вступают ограничения (например, по Организации или Структуре предприятия), платформа принудительно модифицирует каждый запрос, добавляя в него условия проверки прав. Рассмотрим подробнее, что происходит «под капотом».

Если в форме используется динамический список или обработка типа ДокументыПоПартнеруИСделке, запрос часто строится на основе конструкции ОБЪЕДИНИТЬ ВСЕ (UNION ALL) для десятков видов документов (Заказы, Реализации, Счета-фактуры и т.д.). При включенном RLS платформа добавляет к каждой части этого объединения свои соединения с таблицами прав. Если видов документов 25, а ограничение накладывается по двум разрезам (Организация и Подразделение), итоговый SQL-запрос превращается в «монстра» с сотнями соединений. СУБД (например, MS SQL Server или PostgreSQL) зачастую не может построить оптимальный план для такого запроса и выбирает неэффективные методы сканирования таблиц.

Проанализируем ситуацию, описанную в теме: при выборе 15 видов документов всё работает быстро, а при добавлении еще нескольких — время ожидания вырастает до 15 минут. Это классический пример «деградации плана запроса», когда количество условий переходит критическую черту, и оптимизатор СУБД сдается.

Решение 1: Переход на «Производительный» режим RLS

В современных версиях 1С:ERP (начиная с 2.4.5 и выше) реализован инновационный механизм — производительный режим ограничений. В отличие от «классического» режима, который вычисляет права «на лету» в каждом запросе, производительный режим использует предварительно рассчитанные данные.

Как это работает: система создает специальные регистры сведений КлючиДоступаКОбъектам, КлючиДоступаКРегистрам и другие. В этих таблицах заранее записано, к какому «ключу» относится тот или иной документ. Когда пользователь открывает список, SQL-серверу нужно лишь проверить вхождение ключа документа в список разрешенных ключей пользователя. Это на порядки быстрее сложных соединений.

Разберем по шагам, как включить этот режим:

  1. Перейдем в раздел НСИ и администрирование — Настройки пользователей и прав.
  2. Найдем группу Ограничивать доступ на уровне записей.
  3. Установим вариант Производительный (в некоторых версиях это может называться «Использовать обновленные механизмы доступа»).
  4. После включения необходимо дождаться выполнения регламентных заданий. Основное из них — Заполнение данных для ограничения доступа.

Важно: переход на этот режим может занять длительное время (от нескольких часов до суток в зависимости от объема базы), так как системе нужно пересчитать права для всех существующих документов. Рекомендуем сначала протестировать это на копии базы.

Решение 2: Оптимизация динамических списков и ключевого слова РАЗРЕШЕННЫЕ

Часто проблема кроется в использовании ВЫБРАТЬ РАЗРЕШЕННЫЕ в теле сложного запроса динамического списка. Рассмотрим, как можно оптимизировать этот механизм. Если мы используем расширение, мы можем перехватить запрос и изменить его логику.

Выясним причину тормозов в конкретном коде. Вместо того чтобы позволять платформе накладывать RLS на всё объединение, иногда эффективнее сначала получить список ссылок в привилегированном режиме (без проверок), а затем наложить фильтр только на результат. Однако в динамических списках это сделать сложно, поэтому стоит обратить внимание на структуру условий.

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

Решение 3: Проверка иерархических ограничений

Одной из самых «тяжелых» операций для RLS является проверка иерархии (например, ограничение по «Структуре предприятия», когда доступ дается на верхний узел, а пользователь должен видеть все подчиненные). SQL-сервер плохо справляется с рекурсивными запросами внутри RLS.

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

Решение 4: Обслуживание СУБД и очистка кэша

Если «на прошлой неделе всё летало», а сегодня тормозит — велика вероятность, что актуальность статистики SQL-сервера оставляет желать лучшего. RLS крайне чувствителен к статистике индексов.

Рекомендуем выполнить следующие действия:

  1. Запустить Обновление статистики (Update Statistics) для таблиц документов и регистров ключей доступа в консоли SQL-сервера.
  2. Очистить серверный кэш 1С. Для этого необходимо остановить службу сервера 1С и удалить содержимое папки snccntx (кэш параметров сеанса) в каталоге профиля пользователя, от имени которого работает сервер.
  3. Проверить, не запущены ли фоновые процессы, которые могут блокировать таблицы прав (например, массовое перепроведение документов или обновление версии ИБ).

Технический пример оптимизации запроса

Рассмотрим пример того, как платформа может транслировать запрос с RLS. Допустим, у нас есть упрощенный запрос:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    Док.Ссылка,
    Док.Дата
ИЗ
    Документ.РеализацияТоваровУслуг КАК Док

При использовании классического RLS в SQL этот запрос превратится в нечто подобное:


SELECT
    T1._IDRRef,
    T1._Date_Time
FROM
    _Document123 T1
WHERE
    T1._Fld456 IN (SELECT AllowedID FROM #TemporaryAccessTable)
    AND T1._Marked = 0

Если таких таблиц в объединении 25, СУБД вынуждена строить гигантские вложенные циклы. Поэтому, если вы видите, что типовой механизм (например, обработка ДокументыПоПартнеруИСделке) не справляется, лучшим решением будет не «ломать» типовой код, а перевести систему в режим работы с Ключами доступа, где проверка будет идти по одной проиндексированной таблице _InfoRgKeyAccess.

Подводя итог, можно сказать: для ERP 2.4 использование классического RLS на больших объемах данных практически всегда ведет к проблемам производительности. Переход на производительный режим и регулярное обслуживание индексов SQL-сервера — это «золотой стандарт» решения подобных задач.

← На главную