В чем разница между UNION и UNION ALL в SQL?sql-49

Основное различие между UNION и UNION ALL заключается в обработке дубликатов строк и производительности операций. Рассмотрим детально оба оператора.

1. Обработка дубликатов

UNION

SELECT ProductID, ProductName FROM CurrentProducts
UNION
SELECT ProductID, ProductName FROM DiscontinuedProducts
  • Удаляет дубликаты из конечного результата
  • Выполняет дополнительную операцию сортировки и сравнения для выявления дублей
  • Аналогично выполнению DISTINCT на объединенном результате

UNION ALL

SELECT ProductID, ProductName FROM CurrentProducts
UNION ALL
SELECT ProductID, ProductName FROM DiscontinuedProducts
  • Сохраняет все строки, включая дубликаты
  • Не выполняет проверку на дублирование
  • Возвращает простое объединение результатов запросов

2. Производительность

КритерийUNIONUNION ALL
СкоростьМедленнееБыстрее
Ресурсы CPUВышеНиже
ПамятьБольшеМеньше
СортировкаТребуетсяНе требуется

Пример разницы в плане выполнения:

-- UNION (видно оператор Sort/Distinct)
  |--Sort(DISTINCT ORDER BY([ProductID]))
       |--Concatenation

-- UNION ALL (простое объединение)
  |--Concatenation

3. Семантика использования

Когда использовать UNION:

  • Когда нужно исключить дубликаты из результатов
  • Когда дубликаты не имеют смысла для бизнес-логики
  • Когда количество дубликатов невелико

Когда использовать UNION ALL:

  • Когда нужно максимальное быстродействие
  • Когда дубликаты допустимы или требуются
  • При объединении заведомо непересекающихся наборов
  • В ETL-процессах, где важна скорость загрузки

4. Требования к объединяемым запросам

Оба оператора требуют:

  • Одинакового количества столбцов в выборках
  • Совместимых типов данных в соответствующих столбцах
  • Аналогичного порядка столбцов

Пример с ошибкой:

-- Не сработает (разное число столбцов)
SELECT ProductID, ProductName FROM Products
UNION
SELECT ProductID FROM DiscontinuedProducts

5. Особые случаи

Сортировка результатов:

-- Сортировка применяется ко всему результату
SELECT * FROM Table1
UNION ALL
SELECT * FROM Table2
ORDER BY Column1

С агрегатными функциями:

-- UNION ALL сработает быстрее
SELECT COUNT(*) FROM (
    SELECT ProductID FROM CurrentProducts
    UNION ALL
    SELECT ProductID FROM DiscontinuedProducts
) t

С подсказками оптимизатора:

-- Можно использовать OPTION для управления планом
SELECT * FROM Table1
UNION ALL
SELECT * FROM Table2
OPTION (MERGE UNION)

6. Практические рекомендации

  1. Всегда используйте UNION ALL по умолчанию, если не нужна дедупликация
  2. Для больших таблиц разница в производительности может быть значительной
  3. При использовании UNION убедитесь, что столбцы имеют подходящие для сравнения типы
  4. Для сложных объединений рассмотрите альтернативы (JOIN, временные таблицы)

Резюмируем: UNION ALL всегда предпочтительнее для производительности, если сохранение дубликатов допустимо. UNION следует использовать только когда необходимо исключить дублирующиеся строки, понимая накладные расходы на выполнение этой операции. Выбор между ними должен быть осознанным решением, основанным на требованиях к данным и производительности.