Возможность встраивания SQL-функций при фильтрации

Использование SQL-функций для фильтрации позволяет обеспечить проверку более сложных условий, нежели просто сравнение полей с помощью стандартных операций.
Например, можно проверить существование связанной записи в другой таблице, либо собрать какое то комплексное значение с помощью функции и в фильтре проверить его соответствие ожидаемому.

К примеру, предположим у нас есть сущность Организация, а также связанная с ним сущность Роль организации.

image

Перечисление Роль в свою очередь имеет следующие значения:

    /// <summary>
    /// Роли организаций
    /// </summary>
    public enum ContragentRoleEnum
    {
        /// <summary>
        /// Прочие
        /// </summary>
        Other = 1,

        /// <summary>
        /// Эксплуатация
        /// </summary>
        Exploit = 2,

        /// <summary>
        /// Экспертиза
        /// </summary>
        Expert = 3,

        /// <summary>
        /// Владение
        /// </summary>
        Ownership = 4,

        /// <summary>
        /// Аренда
        /// </summary>
        Rent = 5,

        /// <summary>
        /// СРО
        /// </summary>
        SRO = 6,    
        ...        
    }

Задача - в форме организовать выбор Организаций, которые имеют Роль = СРО

Для решения этой задачи есть два пути

  1. Кастомный фильтр в коде на C# (не тема данной статьи)

  2. Фильтр по SQL-функции (а вот это попробуем)

Создадим функцию, которая проверяет наличие соответствующей Роли у переданной Организации:

После чего зарегистрируем эту функцию в качестве расширения сущности Организация и настроим фильтр

После построения приложения, на выбор будут предагаться записи организаций, которые имеют роль СРО, казалось бы задача решена.

Запрос и его план выглядят примерно вот так:

Как мы видим - созданная нами функция будет вызываться для каждой записи в выборке, что замедляет выполнение запроса.

Начиная с версии 5.4.7230, появилась возможность оптимизации подобных запросов. Для этого нужно в настройках SQL-функции отметить чекбокс “Встраивать в фильтры по возможности”:
image

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

а его план выполнения будет более эффективен:

Таким образом, в данном случае, мы получили ускорение выполнения запроса примерно в 45 раз.

Данный вид оптимизации доступен только для функций написанных на языке sql, и оперирующих простыми типами данных.

1 Лайк