Два запроса ищут пользователей без заказов: LEFT JOIN orders ON ... WHERE orders.id IS NULL и WHERE NOT EXISTS (SELECT 1 FROM orders WHERE ...). Что верно о производительности в PostgreSQL?

AВ PostgreSQL оптимизатор обычно приводит оба варианта к одному плану — Anti Join, и производительность одинакова
BВариант с LEFT JOIN + IS NULL всегда быстрее, потому что NOT EXISTS выполняет подзапрос для каждой строки
CВариант с NOT EXISTS всегда быстрее, потому что он прекращает поиск при первом совпадении в подзапросе
DОба варианта выполняются последовательно — сначала полный JOIN, потом фильтрация по NULL
Правильный ответ. Оптимизатор PostgreSQL обычно распознаёт оба паттерна как анти-соединение и строит одинаковый план выполнения — разница в скорости минимальна.

Разбор

Современные оптимизаторы (PostgreSQL, SQL Server, Oracle) умеют преобразовывать LEFT JOIN + IS NULL, NOT EXISTS и даже NOT IN (без NULL) в один оператор Anti Join. В EXPLAIN это видно как Hash Anti Join или Merge Anti Join. На практике для PostgreSQL разница в скорости между первыми двумя подходами пренебрежимо мала. NOT IN может проиграть из-за обработки NULL. Рекомендация: выбирать наиболее читаемый вариант.

Проверь себя · 1/3разбор после ответа
Нужно построить отчёт: по каждому продукту и каждому дню месяца — сумма продаж, включая дни с нулевыми продажами. Как сформировать каркас из всех пар дата-продукт?
Тренировать SQL в Telegram

Ещё вопросы по теме «JOIN и операции множеств»