В одном из сервисов одним из этапов проверки доступа пользователя к сотруднику выполняется проверка на подчинённость
Структура команд, лидов и сотрудников — глубоковложенная иерархия без максимальной глубины
Соответственно, запрос состоял из рекурсивной CTE по командам + сам запрос на проверку принадлежности сотрудника к одной из команд лида
Звучит вроде просто, но на деле там куча мелких условий и джоинов
Так вот, если выдернуть этот из кода и погонять его сырым в базе, то на моей машине при несильно большом объёме данных он занимал 800мс, из которых около 400 постгря производила некие "оптимизации"
Я полез изучать как же всё-таки это дело ускорить, так как по сути 800мс на каждом запросе просто сливаются в унитаз
В итоге решение было даже не в одну строку, а в одно слово — materialized
Ну то есть, объявление CTE стало выглядеть так:with X as materialized ( select ... from ... )
И всё
Результат? Запрос стал выполняться 8мс вместо 800
Всё потому, что результат работы CTE в коде использовался многократно, а постгря при каждом обращении к CTE шла и с нуля пересобирала данные
Обозначив CTE как materialized мы дале постгре понять, что надо один раз обсчитать данные и дальше уже работать как с обычной таблицей
Подойдёт такое решение далеко не всем, не советую толкать это ключевое слово везде в надежде на ускорение, так как у него есть свои минусы, которые к счастью в этом конкретном случае были совершенно неактуальны
Добавить комментарий