Условие
В чём основные различия между UNION и UNION ALL? Когда какой выбрать?
Решение
| UNION | UNION ALL | |
|---|---|---|
| Дубликаты | Удаляет | Сохраняет |
| Скорость | Медленнее (требуется DISTINCT) | Быстрее |
| Сортировка | Часто неявная (для дедупликации) | Нет |
| Память | Больше | Меньше |
Оба требуют:
- Одинаковое число столбцов в подзапросах.
- Совместимые типы в соответствующих колонках.
Пример
-- Заказы из двух систем (ресторан + курьер)
SELECT order_id, amount FROM restaurant_orders
UNION
SELECT order_id, amount FROM courier_orders;
-- если заказ был и там, и там → одна строка
SELECT order_id, amount FROM restaurant_orders
UNION ALL
SELECT order_id, amount FROM courier_orders;
-- если заказ был и там, и там → две строкиКогда что использовать
| Сценарий | Выбор |
|---|---|
| Объединение логов из шардов (заранее не пересекаются) | UNION ALL (быстрее) |
| Объединение данных из систем, где может быть дубль | UNION |
| Подсчёт уникальных записей | UNION |
WITH RECURSIVE для CTE |
UNION ALL (обычно требуется) |
Производительность
-- если знаешь, что дубликатов нет — не плати за DISTINCT
SELECT * FROM january_orders
UNION ALL -- быстрее, чем UNION
SELECT * FROM february_orders;UNION под капотом обычно делает либо SORT + UNIQUE, либо HASH AGGREGATE. На больших объёмах это серьёзный оверхед.
Совместимость типов
-- ОК: оба INT
SELECT 1 UNION SELECT 2;
-- ОК: SQL приведёт к общему типу (например, NUMERIC)
SELECT 1::INT UNION SELECT 2.5::NUMERIC;
-- Ошибка: TEXT и INT несовместимы напрямую
SELECT 'a' UNION SELECT 1;Подводные камни
ORDER BYв подзапросе UNION — игнорируется или вызывает ошибку. Сортировка только в финале.- Имена колонок — берутся из первого SELECT, остальные могут иметь любые алиасы.
NULLпри сравнении — вUNIONдве строки с одинаковыми значениями иNULL'ами считаются дублем (неожиданно для тех, кто помнит про трёхзначную логику).UNION≠UNION DISTINCT— это синонимы, но второй запись более явный (и доступен не везде).
Эталонный ответ
UNION удаляет дубликаты и медленнее. UNION ALL сохраняет дубликаты и быстрее. Если знаете, что дублей нет — всегда UNION ALL.