LATERAL JOIN

Тема дорожной карты · PostgreSQL

LATERAL JOIN в PostgreSQL — специальный синтаксис соединения, позволяющий подзапросу в правой части ссылаться на столбцы из таблиц, расположенных левее во фразе FROM, что фактически превращает подзапрос в коррелированный цикл, выполняемый один раз для каждой строки ведущего отношения. Ключевое слово LATERAL ставится перед подзапросом или функцией, возвращающей множество строк: SELECT u.*, recent.* FROM users u, LATERAL (SELECT * FROM orders WHERE user_id = u.id ORDER BY created_at DESC LIMIT 3) recent — этот запрос возвращает три последних заказа для каждого пользователя за один запрос к реляционной базе данных. Данный паттерн эффективнее коррелированных подзапросов в списке SELECT, поскольку планировщик PostgreSQL может выбирать стратегии Nested Loop или Hash Join и применять методы оптимизации запросов, такие как индексное сканирование по латерально связанному ключу соединения. LATERAL JOIN также является стандартным механизмом для вызова функций, возвращающих множество строк — jsonb_array_elements() или unnest() — относительно столбца каждой строки, что делает его незаменимым при работе с массивами и массивами JSONB в PostgreSQL.

Как это работает

LATERAL JOIN соединяет данные между таблицами: INNER, LEFT/RIGHT/FULL OUTER, CROSS, LATERAL (per-row подзапрос), SELF (alias той же таблицы). View — сохранённые запросы (CREATE VIEW v AS SELECT ...); материализованные view (CREATE MATERIALIZED VIEW ...) кешируют результат на диск, требуют REFRESH. Оконные функции (OVER (PARTITION BY ... ORDER BY ...)) считают per-row агрегацию без коллапса строк. CTE (WITH ... AS) именуют подзапросы для читаемости.

Когда применять

View — для энкапсуляции сложных запросов, переиспользуемых вызывающими: версионированная API-поверхность над схемой. Материализованные view — когда подлежащий запрос дорогой, staleness секунд-часов допустим. LATERAL — когда подзапросу нужны колонки внешнего (top-N per group — канонический пример). Оконные функции вместо сложных self-join — для running totals, рангов, перцентилей.

Типичные ошибки

Ловушки LATERAL JOIN: глубоко вложенные view (SELECT из view, join-ящего три view — планировщик видит один большой запрос, может выбрать плохой план); никогда не рефрешат materialized view (stale данные неделями); FULL OUTER JOIN, где надо INNER (NULL-потоп); cartesian-взрыв от пропущенного JOIN-условия (5 таблиц × 5 unrelated строк = миллионы). Всегда EXPLAIN для join перед деплоем.

Связанные понятия

Полезные ресурсы