При разработке и доработке типовых конфигураций 1С можно столкнуться с ситуацией, когда простейший выбор реквизита из справочника начинает выполняться крайне долго или полностью виснет. Рассмотрим типичный пример такого запроса:
ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ ПЕРВЫЕ 51
ТаблицаСправочника.AB_Партнер КАК AB_Партнер
ИЗ
Справочник.Номенклатура КАК ТаблицаСправочника
ГДЕ
ТаблицаСправочника.ВидНоменклатуры = &ВидНоменклатуры
На первый взгляд запрос кажется легковесным. Однако при выполнении в файловой базе или под пользователем с ограниченными правами время ожидания ответа может исчисляться минутами. Проанализируем причины такого поведения и разберем варианты решения проблемы.
Зависание происходит из-за специфики совместной работы нескольких механизмов платформы 1С и СУБД:
РАЗРЕШЕННЫЕ на лету подставляет в запрос вложенные условия проверки прав. Если у пользователя включен RLS на справочник Номенклатура или связанный справочник, итоговый SQL-запрос существенно усложняется.ПЕРВЫЕ без ключевого слова УПОРЯДОЧИТЬ ПО не дает СУБД опереться на существующие индексы таблицы.Конструкции РАЗЛИЧНЫЕ и СГРУППИРОВАТЬ ПО дают идентичный результат по составу данных, однако оптимизатор СУБД строит для них совершенно разные планы выполнения. Замена РАЗЛИЧНЫЕ на группировку позволяет кардинально ускорить выборку:
ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 51
ТаблицаСправочника.AB_Партнер КАК AB_Партнер
ИЗ
Справочник.Номенклатура КАК ТаблицаСправочника
ГДЕ
ТаблицаСправочника.ВидНоменклатуры = &ВидНоменклатуры
СГРУППИРОВАТЬ ПО
ТаблицаСправочника.AB_Партнер
На практике этот простой шаг сокращает время выполнения запроса с нескольких минут до 1 секунды.
Если запрос формируется динамически или входит в состав более сложного алгоритма, логично разделить получение данных и отсечение уникальных значений на два независимых шага. Рассмотрим этот подход по шагам:
ГДЕ и помещаем их во временную таблицу.
ВЫБРАТЬ РАЗРЕШЕННЫЕ
ТаблицаСправочника.AB_Партнер КАК AB_Партнер
ПОМЕСТИТЬ ВТ_Партнеры
ИЗ
Справочник.Номенклатура КАК ТаблицаСправочника
ГДЕ
ТаблицаСправочника.ВидНоменклатуры = &ВидНоменклатуры;
ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 51
ВТ_Партнеры.AB_Партнер КАК AB_Партнер
ИЗ
ВТ_Партнеры КАК ВТ_Партнеры
В этом случае платформа сначала выполнит проверку RLS и отбор по виду номенклатуры, а обработку уникальности РАЗЛИЧНЫЕ выполнит на уже небольшом объеме данных из временной таблицы.
Разберем дополнительные настройки на уровне конфигуратора и текста запроса, которые помогают повысить скорость работы:
ВидНоменклатуры в конфигураторе установлено свойство **Параметры индексации** в значение Индексировать или Индексировать с доп. упорядочиванием. Индексировать само выбираемое поле AB_Партнер без индексации поля фильтрации не даст результата.
ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 51
ВЫРАЗИТЬ(ТаблицаСправочника.AB_Партнер КАК Справочник.Партнеры) КАК AB_Партнер
ИЗ
Справочник.Номенклатура КАК ТаблицаСправочника
ГДЕ
ТаблицаСправочника.ВидНоменклатуры = &ВидНоменклатуры
СГРУППИРОВАТЬ ПО
ТаблицаСправочника.AB_Партнер
Если алгоритм выполняется в фоновом задании или сертифицированном сервисном коде, где не требуется ограничение прав на уровне строк, целесообразно временно отключить RLS с помощью функции УстановитьПривилегированныйРежим(Истина). В этом случае ключевое слово РАЗРЕШЕННЫЕ будет проигнорировано платформой, что исключит подстановку тяжелых подзапросов прав доступа.