Разработчики систем на платформе «1С:Предприятие» часто сталкиваются с неприятной ситуацией: запрос, который под полными правами администратора выполняется мгновенно (за доли секунды), у обычного пользователя с ограничениями доступа на уровне записей (RLS) начинает жутко тормозить, выполняясь по 10–20 секунд и более. Особенно остро эта проблема проявляется в динамических списках документов или справочников.
В рамках этой статьи мы подробно разберем, почему возникает такая деградация производительности, рассмотрим внутренние механизмы платформы 1С и СУБД, проанализируем коварный эффект Parameter Sniffing и изучим практические методы решения проблемы.
Когда пользователь с ограниченными правами выполняет запрос, платформа 1С автоматически модифицирует его перед отправкой в СУБД. Даже если в исходном коде не используется ключевое слово РАЗРЕШЕННЫЕ, система все равно обязана отфильтровать данные согласно действующим правилам RLS.
В обычном (стандартном) режиме работы RLS модификация происходит «на лету». К исходному, казалось бы, простому запросу платформа принудительно добавляет многочисленные левые соединения (LEFT JOIN) и вложенные подзапросы к таблицам прав доступа, групп пользователей, видов доступа и профилей. В итоге лаконичный запрос из 10 строк превращается на стороне СУБД в сложную структуру из сотен строк кода. Для СУБД стоимость выполнения такого запроса возрастает по экспоненте, так как вместо прямого чтения таблицы ей приходится связывать огромные массивы данных.
Наиболее критично RLS бьет по динамическим спискам. По умолчанию динамический список работает по принципу постраничной выборки, запрашивая у СУБД порции данных (например, первые 45 строк) с помощью конструкции SELECT TOP 45.
Рассмотрим, как это происходит на уровне базы данных:
Многие разработчики замечают странное поведение системы при тестировании производительности: стоит добавить пользователю немного прав, как запрос начинает «летать» за полсекунды. После возвращения прав в исходное состояние запрос продолжает работать быстро. Однако после очистки кэша планов запросов или обновления статистики СУБД производительность снова падает до 12–15 секунд.
Этот эффект в Microsoft SQL Server называется Parameter Sniffing (чувствительность к параметрам):
Index Seek).Index Scan), все последующие запросы других пользователей будут использовать этот же медленный план.Ниже приведен пример концептуального SQL-запроса, в который платформа 1С превращает обычную выборку документов при наложении стандартных ограничений RLS:
SELECT TOP 45
T1._IDRRef,
T1._Number,
T1._Date_Time
FROM
_Document150 T1
LEFT OUTER JOIN _InfoReg200 T2 ON (T2._Fld201RRef = T1._Fld151RRef)
WHERE
T2._Fld202RRef IN (SELECT _Fld301RRef FROM _InfoReg300 WHERE _Fld302RRef = @P1)
Такие вложенные конструкции крайне тяжело поддаются оптимизации стандартными средствами СУБД без точечной настройки индексов.
---
Это самый надежный и точечный метод решения проблемы, который помог автору обсуждения. Типовые конфигурации 1С проектируются универсально, и индексы в них создаются под стандартные сценарии. Однако специфические правила RLS в вашей базе могут требовать совершенно иных индексов.
Выполним оптимизацию по шагам:
DBMSSQL).Ctrl + M).Index Scan (сканирование индекса) или Table Scan (сканирование таблицы), которые забирают наибольший процент стоимости запроса. Часто сама SSMS зеленым текстом подсказывает, какого именно индекса ей не хватает для ускорения выборки.Организация или Подразделение) в сочетании с полем ссылки на объект и датой.Важно: Помните, что создание индексов напрямую в СУБД в обход платформы 1С может привести к их удалению при очередной реструктуризации базы данных (например, при обновлении конфигурации). Поэтому правильнее создавать эти индексы в самой конфигурации 1С, добавляя соответствующие реквизиты в свойство «Индексировать» или создавая критерии отбора.
Если ваша конфигурация разработана на базе современной версии «Библиотеки стандартных подсистем» (БСП 3.x), вам доступен кардинально новый механизм — Производительный (универсальный) режим работы RLS.
Рассмотрим, как работают оба режима, чтобы понять разницу:
КлючиДоступаКОбъектам, КлючиДоступаПользователей). При чтении данных СУБД больше не вычисляет сложные RLS-условия, а просто делает быстрое соединение с плоской таблицей ключей доступа.Для включения этого режима выполните следующие действия:
Обратная сторона: Производительный режим RLS существенно увеличивает время записи и проведения документов, так как системе требуется обновлять ключи доступа в транзакции записи. Также это приводит к росту размера базы данных за счет таблиц кэша ключей.
Если предыдущие методы недоступны, мы можем облегчить жизнь СУБД, оптимизировав сам текст запроса динамического списка:
Ссылка.Контрагент.ОсновнойДоговор, и на справочники контрагентов или договоров также наложен RLS, платформа принудительно добавит проверки прав по всей этой цепочке связей. Постарайтесь минимизировать количество таких полей в списке.LEFT JOIN). Помните, что динамический список — это инструмент оперативной работы с реестром документов, а не полноценный аналитический отчет.Универсального решения «в один клик» для проблем с RLS не существует. В простых базах с небольшим объемом данных отлично помогает переход на производительный режим RLS в БСП. На крупных, высоконагруженных внедрениях наилучшие результаты дает ручной анализ планов запросов в SQL Server и точечное построение составных индексов под конкретные профили групп доступа пользователей.