Работа с механизмом критериев отбора в крупных конфигурациях, таких как 1С:ERP Управление предприятием или 1С:Комплексная автоматизация, часто становится «узким местом» производительности. Типовой запрос к критерию СвязанныеДокументы может выполняться десятки секунд, что недопустимо для оперативной работы пользователя. В рамках данной статьи мы подробно разберем, почему это происходит и как мы можем значительно ускорить эти процессы.
Прежде всего, проанализируем ситуацию: что происходит «под капотом» платформы 1С, когда мы обращаемся к виртуальной таблице критерия отбора? Важно понимать, что критерий отбора — это не физическая таблица в базе данных SQL, а декларативное описание правил сбора данных. Когда мы выполняем запрос к КритерийОтбора.СвязанныеДокументы, платформа динамически генерирует SQL-запрос, представляющий собой гигантское объединение (UNION ALL) множества таблиц.
В ERP критерий СвязанныеДокументы может включать в себя данные из 150 и более различных типов документов. Для каждого типа документа в запрос включаются его шапка, а зачастую и несколько табличных частей. В итоге SQL-сервер получает «портянку» из более чем сотни подзапросов. Рассмотрим основные причины деградации производительности в таких условиях:
Одной из самых частых причин замедления является использование слова РАЗРЕШЕННЫЕ в запросе. Выясним причину: при включенном механизме RLS (Restriction at Leaf Level) платформа модифицирует каждую из 150+ ветвей UNION ALL, добавляя туда дополнительные соединения (JOIN) с таблицами прав доступа. Это увеличивает сложность SQL-запроса в геометрической прогрессии.
Проанализируем ситуацию на примере: если под полными правами запрос выполняется 10 секунд, то под обычным пользователем с RLS он может «уйти в вечность» или вызвать ошибку превышения времени ожидания.
Решение: Если бизнес-логика позволяет, выполняйте поиск по критерию отбора в привилегированном режиме на сервере, исключив из текста запроса слово РАЗРЕШЕННЫЕ. Это позволит платформе сформировать максимально чистый SQL-запрос без наслоения проверок прав доступа.
// Пример вызова в привилегированном модуле
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СвязанныеДокументы.Ссылка КАК Ссылка
|ИЗ
| КритерийОтбора.СвязанныеДокументы(&ЗначениеКритерия) КАК СвязанныеДокументы";
Запрос.УстановитьПараметр("ЗначениеКритерия", ДокументСсылка);
Результат = Запрос.Выполнить().Выгрузить();
Посмотрим на свойства объектов, входящих в критерий. Платформа 1С автоматически создает индексы для полей, которые включены в критерий отбора. Однако есть нюансы, которые мы должны учитывать:
Индексировать или Индексировать с дополнительным упорядочиванием, критерий будет использовать этот существующий индекс.ЛюбаяСсылка, производительность всегда будет ниже. Старайтесь ограничивать типы реквизитов, входящих в критерий.Рассмотрим совет опытных архитекторов: если типовой критерий СвязанныеДокументы работает слишком медленно из-за своей избыточности, попробуйте создать собственный специализированный критерий отбора. Включите в него только те 10-15 типов документов, которые реально используются в вашей цепочке бизнес-процессов. Это сократит количество UNION ALL в разы.
Если оптимизация самого критерия не приносит желаемого результата, разберем альтернативные подходы, которые часто применяются в ERP для повышения производительности.
В отличие от критерия отбора, Журнал документов — это физическая таблица в СУБД. Если все необходимые документы включены в определенный журнал и в нем есть соответствующие графы, запрос к журналу с фильтром по графе будет работать на порядок быстрее, чем обращение к критерию отбора. Это связано с тем, что SQL-серверу гораздо проще выполнить поиск по одной проиндексированной таблице, чем соединять сотню других.
Если мы заранее знаем, в каких именно документах может находиться ссылка на наш объект, мы можем написать запрос вручную. Посмотрим на пример кода, который заменяет универсальный критерий направленным поиском:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ Ссылка ИЗ Документ.ЗаказКлиента ГДЕ ОбъектРасчетов = &Объект
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ Ссылка ИЗ Документ.РеализацияТоваровУслуг ГДЕ ОбъектРасчетов = &Объект
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ Ссылка ИЗ Документ.ПоступлениеБезналичныхДенежныхСредств ГДЕ ОбъектРасчетов = &Объект";
Запрос.УстановитьПараметр("Объект", НужныйОбъект);
Такой подход, несмотря на кажущуюся громоздкость, работает в разы быстрее, так как мы точно указываем СУБД, где искать данные, не заставляя её просматривать сотни ненужных таблиц (например, документы производства или кадровые приказы, которые точно не связаны с объектом расчетов).
В некоторых случаях оправдано создание собственного регистра сведений (например, ГрафСвязейДокументов), который заполняется при проведении документов. Это позволяет свести поиск связей к простейшему запросу по одной таблице регистра. В ERP похожий механизм используется для некоторых подсистем (например, связи с внутренними документами).
Иногда причина долгого выполнения кроется в настройках самого сервера базы данных. Проанализируем два важных параметра MS SQL Server:
Для ускорения критериев отбора в 1С:ERP мы рекомендуем придерживаться следующего алгоритма:
СвязанныеДокументы), создайте свой, более узкий критерий.Используя эти методы, вы сможете сократить время получения связанных документов с десятков секунд до долей секунды, что существенно повысит комфорт работы пользователей в системе.