Два запроса ищут пользователей без заказов: 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, потом фильтр по IS 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. Рекомендация: выбирать наиболее читаемый вариант.

Можно заниматься бесплатно

Готовим вопросы…

Три вопроса по теме этой страницы, с объяснениями.

Продолжить в браузере

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