При разработке и сопровождении конфигураций 1С разработчики часто сталкиваются с ситуацией, когда один и тот же отчет, динамический список или процедура обработки данных отрабатывает у одного пользователя за считанные секунды, а у другого — зависает на несколько минут. Разберем детально, почему это происходит и как устранить разницу во времени выполнения.
Основная и наиболее частая причина расхождения по времени — работа механизма ограничения прав на уровне записей и полей (RLS — Record Level Security). Даже если в конфигураторе написан одинаковый текст запроса, на сторону СУБД отправляются совершенно разные SQL-запросы в зависимости от назначенных ролей текущего пользователя.
Проанализируем механизм влияния прав на производительность:
EXISTS или IN.Рассмотрим случай, когда разница во времени наблюдается на этапе программного вывода схемы компоновки данных (СКД):
РезТаблица = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(РезТаблица);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
Метод ПроцессорВывода.Вывести(...) выполняет не только построчное чтение выборки, но и получение представлений ссылочных данных. Если для ссылочных полей не настроено явное выражение представления, платформа делает дополнительные соединения с таблицами справочников и документов. Если на эти объекты у пользователя действуют условия RLS, проверка прав накладывается на каждое ссылочное поле, кратно замедляя обработку.
Разберем практические шаги для устранения проблемы разной скорости работы:
УстановитьПривилегированныйРежим(Истина);
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
РезТаблица = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(РезТаблица);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
УстановитьПривилегированныйРежим(Ложь);
Оплачено), по которому строятся соединения или отборы, убедимся, что для него в свойствах конфигуратора включено свойство Индексировать. Отсутствие индекса в связке с наложенными условиями RLS заставляет СУБД повторно сканировать весь объем данных.ПРЕДСТАВЛЕНИЕ() или обращение к реквизитам наименования. Также полезно отключить флаг «Автополе», чтобы исключить автоматическую выборку скрытых ссылочных данных.DBMSSQL / DBPOSTGRS или воспользуемся трассировкой запросов СУБД (SQL Server Profiler). Это позволит увидеть реальный текст запроса с внедренным кодом RLS и оценить план выполнения.Если результат выгружается напрямую в коллекцию ТаблицаЗначений без использования интерактивных группировок, надежнее использовать прямой запрос на языке 1С. В тексте запроса следует явно применить операторы ВЫРАЗИТЬ и функции получения представлений, после чего выгрузить данные методом Выгрузить(), что полностью исключит накладные расходы процессора компоновки данных.