Что такое LATERAL и зачем он в JOIN?
В стандартном SQL таблицы в JOIN — это изолированные миры. Подзапрос не может «заглянуть» в таблицу, которая стоит левее него. Он должен выполниться целиком до того, как база начнет склеивать его с основным результатом.
Метафора: Обычный JOIN — это ящик с котом Шредингера. Его можно открыть и узнать, жив ли кот, но , ящик может быть большим и в нем может быть много котовых принадлежностей, так что придется разобрать все, чтобы узнать состояние кота.
LATERAL — позволяет сделать щелку в ящике (или несколько), через которую можно посмотреть на кота, не открывая и не разбирая ящик.
Реальный кейс: Задача: Получить последнюю дату в огромной таблице.
Как было: Запрос через WHERE indicator_type ANY (ARRAY[...]). База видела условия и начинала поиск по всей таблице. Даже с индексами это долго: планировщик пытается охватить всё разом, тратя ресурсы на лишнее сканирование.
Как стало :
Чтобы база не «думала», прописали алгоритм действий.
- Сделали композитный индекс на indicator_type, date_type, date DESC
2)Создали комбинации, по которым хотим получить результаты :
SELECT * FROM (VALUES (99), (100)) AS t(indicator)CROSS JOIN (VALUES ('Нарастающим итогом с начала месяца'), ('За месяц')) AS d(dt_type) Получили 4 строки — все нужные нам наборы фильтров.
- Подключили LATERAL:
CROSS JOIN LATERAL ( SELECT css.date FROM bi.start_screen ss WHERE ss.indicator_type = params.indicator AND ss.date_type = params.dt_type ORDER BY ss.date DESC LIMIT 1 ) sub;
В чем «магия» ? LATERAL работает как цикл FOR EACH в мире SQL
Мы превратили неопределенный поиск в 4 точечных укола.
К каждой из наших 4 строк с фильтрами мы добавили дату через LATERAL. Благодаря строгим равенствам (=) внутри подзапроса, база использует композитный индекс.
Движку больше не нужно сканировать таблицу. Он берет наш набор фильтров, идет в индекс, забирает ровно одно (самое свежее по дате) значение и переходит к следующей комбинации. В конце мы просто выбираем одно максимальное значение из этих четырех.
Итог: Мы превратили тяжелый поиск в алгоритмический проход по точкам. Скорость выросла в разы.