Как повысить производительность RLS при большом количестве складов и подразделений в 1С:ERP

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

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

В этой статье мы подробно разберем, почему классический механизм RLS вызывает сильные зависания интерфейса (вплоть до невозможности открыть список или создать новый документ), проанализируем физику этого процесса на уровне СУБД и рассмотрим несколько эффективных практических способов решения данной проблемы — от быстрых настроек в интерфейсе до глубокой оптимизации архитектуры прав.

Почему классический RLS работает медленно при большом числе значений доступа?

Для того чтобы понять, как решить проблему, давайте сначала выясним ее причину. При использовании стандартного (классического) режима RLS платформа 1С «на лету» модифицирует каждый запрос, отправляемый к базе данных SQL. Когда пользователь открывает форму списка документов ПТУ (Приобретение товаров и услуг), платформа не просто считывает данные из таблицы документов. Она автоматически добавляет к исходному запросу неявные левые соединения (LEFT JOIN) с таблицами прав доступа.

Основным источником информации о правах в классическом RLS выступает регистр сведений РегистрСведений.ЗначенияГруппДоступа. Когда у пользователя настроены ограничения по нескольким независимым аналитикам (в нашем примере — 42 склада и 38 подразделений), СУБД вынуждена оценивать огромную декартову матрицу возможных пересечений прав для каждой строки документа. Оптимизатор запросов СУБД (будь то Microsoft SQL Server или PostgreSQL) при попытке построить оптимальный план выполнения такого перегруженного запроса сталкивается с так называемым «таймаутом оптимизатора» (Optimizer Timeout). В результате СУБД отказывается от использования индексов и скатывается к полному сканированию таблиц (Table Scan), что приводит к зависаниям и длительному ожиданию открытия формы.

Решение 1. Переход на производительный режим RLS (рекомендуемый системный подход)

Если вы работаете на современных версиях 1С:ERP (на базе БСП 3.x), то лучшим решением будет полный отказ от классического RLS в пользу производительного режима работы RLS (также известного как RLS через ключи доступа).

Разберем по шагам, как работает этот режим и почему он работает быстрее:

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

Чтобы включить этот режим, выполните следующие действия в интерфейсе программы:

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

Решение 2. Использование групп доступа складов и подразделений

Если по каким-то причинам вы вынуждены оставаться на классическом RLS, крайне не рекомендуется накладывать ограничения прав непосредственно на элементы справочника Справочники.Склады или Справочники.СтруктураПредприятия. Ограничение по десяткам конкретных элементов — это заведомо проигрышный путь.

Рассмотрим, как оптимизировать структуру данных с помощью групп доступа по аналогии с номенклатурой или партнерами:

  1. Создайте специальный справочник или используйте существующий механизм групп доступа. В справочнике Склады добавьте реквизит ГруппаДоступа.
  2. Разбейте все ваши 42 склада на 3–5 логических групп (например: «Склады розничной торговли», «Оптовые склады», «Региональные филиалы»).
  3. Аналогичным образом поступите со структурой предприятия (подразделениями), объединив их в несколько групп доступа.
  4. В настройках прав пользователей вместо 42 складов и 38 подразделений укажите соответствующие группы доступа.

В результате СУБД в запросе RLS будет оперировать не десятками индивидуальных записей, а всего лишь несколькими группами доступа. Размер таблицы пересечений прав уменьшится на порядки, и производительность списков мгновенно восстановится.

Решение 3. Тонкая настройка шаблонов ограничений БСП

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

Например, в шаблонах ограничений можно найти типовой код БСП:


#Если СтрСодержит(&ВидыДоступаБезГруппДляЗначенияДоступа, ",#Параметр(4),") #Тогда
ВЫБРАТЬ ПЕРВЫЕ 1 ИСТИНА
ИЗ РегистрСведений.ЗначенияГруппДоступа КАК Значения
ГДЕ
    Значения.ГруппаДоступа = ГруппыДоступа.Ссылка
    И Значения.ЗначениеДоступа = Т.#Параметр(5)

Проанализируем этот участок кода. Мы можем жестко модифицировать это условие в шаблоне конкретно под ваши виды доступа (Склады или Подразделения), минуя универсальные ресурсоемкие проверки параметров БСП. Это позволит сократить количество соединений и передаваемых параметров в SQL-запрос.

Решение 4. Принудительное наложение жестких отборов в списках (быстрый обходной путь)

Иногда требуется решить проблему «здесь и сейчас», без изменения конфигурации и длительного пересчета ключей доступа. В этом случае отлично помогает наложение жестких отборов непосредственно в форме списка документов.

Выясним причину, почему отбор по организации или периоду ускоряет работу RLS:

Когда пользователь открывает пустой список ПТУ, СУБД пытается применить правила RLS ко всей таблице документов за все время. Если же мы программно или интерактивно устанавливаем жесткий отбор (например, по конкретной Организации или текущему Месяцу), этот фильтр транслируется в секцию WHERE результирующего SQL-запроса.

Поскольку поле Организация хорошо проиндексировано СУБД, база данных сначала быстро отсекает ненужные строки по индексу организации, оставляя лишь малую часть выборки. И уже к этой небольшой выборке строк СУБД применяет тяжелые левые соединения по складам и подразделениям. Нагрузка на сервер снижается в сотни раз, список открывается мгновенно.

Рекомендуется сделать предопределенные отборы (например, по умолчанию показывать документы только за последний месяц) обязательными для пользователей с ограниченными правами.

Решение 5. Полный отказ от RLS на чтение с проверкой прав «при записи»

Если требования безопасности вашей компании допускают это, рассмотрите радикальный, но максимально эффективный с точки зрения производительности вариант — отказ от RLS на уровне чтения списков.

Рассмотрим этот подход подробнее:

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


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем, есть ли у текущего пользователя права на запись документа по складу
    Доступ Разрешен = ПроверитьДоступКЗначению(ЭтотОбъект.Склад, ПараметрыСеанса.ТекущийПользователь);
    
    Если Не ДоступРазрешен Тогда
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
            НСтр("ru = 'У вас нет прав на создание или изменение документов по складу: '") + ЭтотОбъект.Склад
        );
        Отказ = Истина;
    КонецЕсли;
    
КонецПроцедуры

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

Резюме и рекомендации

Для кардинального решения проблемы медленной работы RLS при большом числе складов и подразделений мы рекомендуем придерживаться следующего плана действий:

  1. В первую очередь проверьте статус настройки RLS в вашей ERP. Если используется классический режим, переведите систему в Производительный режим RLS. Это решает большинство проблем производительности на современных конфигурациях 1С.
  2. Если перевод в производительный режим невозможен, откажитесь от ограничений по конкретным складам. Объедините склады в Группы доступа складов и настройте права через них.
  3. Настройте формы динамических списков так, чтобы пользователи обязательно открывали их с установленным отбором по организации или периоду (например, за текущий квартал).
  4. Если для бизнеса важна только невозможность редактирования чужих документов, а просмотр разрешен — полностью отключите RLS на чтение и реализуйте проверку прав в модулях объектов ПередЗаписью.
← На главную