Как оптимизировать запрос при фильтрации по полю с типом «Определяемый тип» в 1С

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

При работе с запросами в 1С:Предприятии программисты часто сталкиваются с необходимостью фильтрации данных по полям, имеющим составной тип или Определяемый тип. Особенность таких полей заключается в том, что они могут хранить ссылки на различные объекты метаданных (справочники, документы и т.д.). Неправильный подход к написанию условия в секции ГДЕ может привести не только к ошибкам выполнения запроса, но и к значительным потерям производительности. Разберем подробно, как правильно накладывать условия на такие поля, и проанализируем, почему стандартные конструкции могут давать сбой.

Проблема использования оператора ВЫРАЗИТЬ в условиях

Рассмотрим ситуацию, когда разработчик пытается отфильтровать данные, используя оператор ВЫРАЗИТЬ. Часто это выглядит следующим образом:


ГДЕ
    ВЫРАЗИТЬ(ДействияЗадач.ВидПриложения КАК Справочник.ВидыДокументов)

Проанализируем, почему этот код вызывает ошибку. Оператор ВЫРАЗИТЬ предназначен для явного приведения типа значения в выборке. Однако в секции ГДЕ платформа ожидает логическое выражение, результат которого — «Истина» или «Ложь». Само по себе приведение к типу не является логическим условием. Чтобы такая конструкция заработала в фильтре, ее пришлось бы сравнивать с чем-то еще, например:


ГДЕ
    ВЫРАЗИТЬ(ДействияЗадач.ВидПриложения КАК Справочник.ВидыДокументов) ЕСТЬ НЕ NULL

Но даже в таком виде это решение далеко от оптимального. Использование ВЫРАЗИТЬ заставляет систему выполнять лишние преобразования типов для каждой строки таблицы. Если типов внутри Определяемого типа много, это создаст избыточную нагрузку на СУБД.

Оптимальный метод: использование оператора ССЫЛКА

Наиболее правильным и производительным способом проверки типа в запросе 1С является оператор ССЫЛКА. С точки зрения SQL, этот оператор транслируется в максимально простую и быструю проверку идентификатора типа в соответствующей колонке таблицы.

Рассмотрим пример правильного написания условия:


ГДЕ
    ДействияЗадач.ВидПриложения ССЫЛКА Справочник.ВидыДокументов

Почему это работает быстрее? Выясним причину, заглянув «под капот» базы данных. Когда вы используете Определяемый тип, СУБД хранит данные в нескольких колонках: одна для идентификатора типа и другие для уникальных идентификаторов (GUID) конкретных объектов. Оператор ССЫЛКА проверяет только колонку идентификатора типа. Это позволяет оптимизатору SQL эффективно отсекать ненужные записи еще до того, как начнется чтение данных самого объекта.

Решение через ТИПЗНАЧЕНИЯ и ТИП

Иногда возникают ситуации, когда конструктор запроса или сама платформа не принимают конструкцию ССЫЛКА. Это часто случается при использовании расширений конфигурации, когда метаданные не успели корректно обновиться в кэше. В этом случае рабочим вариантом будет использование функций ТИПЗНАЧЕНИЯ и ТИП.

Посмотрим на пример кода, который помог автору темы:


ГДЕ
    ТИПЗНАЧЕНИЯ(ДействияЗадач.ВидПриложения) = ТИП(Справочник.ВидыДокументов)

Хотя этот вариант функционально идентичен оператору ССЫЛКА, технически он может работать чуть медленнее на огромных массивах данных, так как функция ТИПЗНАЧЕНИЯ вычисляется для каждой строки. Однако на практике разница часто нивелируется оптимизатором запросов 1С.

Влияние расширений на работу с типами

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

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

Технические нюансы хранения в SQL

Разберем подробнее, как устроены поля с составным типом на уровне СУБД. При создании поля типа Определяемый тип платформа 1С создает в SQL-таблице структуру, зависящую от количества входящих в него типов. Если типов много, таблица «раздувается», так как для каждого типа выделяется место под GUID.

Для оптимизации производительности придерживайтесь следующих правил:

Итоги и рекомендации

Подводя итог нашему анализу, можно составить пошаговый алгоритм действий при возникновении ошибок фильтрации по составным типам:

  1. Проверить правильность написания имен объектов и реквизитов.
  2. Попробовать использовать ССЫЛКА как наиболее быстрый вариант.
  3. Если ССЫЛКА выдает ошибку в конструкторе (особенно в расширении), использовать связку ТИПЗНАЧЕНИЯ(...) = ТИП(...).
  4. Избегать использования ВЫРАЗИТЬ внутри секции ГДЕ для фильтрации типов.

Соблюдение этих простых правил позволит вам писать чистый, быстрый и отказоустойчивый код запросов, который будет эффективно работать даже при больших объемах данных и сложной структуре метаданных.

← На главную