Как работает JOIN под капотом в базе данных?

«Как работает JOIN под капотом в базе данных?» — вопрос из категории Базы данных, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Оптимизатор СУБД выбирает один из нескольких алгоритмов для выполнения JOIN, основываясь на статистике таблиц, наличии индексов и доступной памяти. Основные алгоритмы:

1. Nested Loop Join

  • Принцип: Для каждой строки внешней (левой) таблицы выполняется полное сканирование внутренней (правой) таблицы для поиска совпадений.
  • Эффективность: Хорош для небольших таблиц или когда во внутренней таблице есть индекс по ключу соединения.
  • Пример сценария:
    -- Оптимизатор может выбрать Nested Loop, если Customers маленькая или есть индекс по CustomerID
    SELECT * FROM Orders o
    JOIN Customers c ON o.CustomerID = c.CustomerID;

2. Hash Join

  • Принцип: Созется хеш-таблица для меньшей таблицы (по ключу соединения). Затем сканируется большая таблица, и для каждой ее строки вычисляется хеш для быстрого поиска совпадения в хеш-таблице.
  • Эффективность: Оптимален для больших несортированных наборов данных, где нет подходящих индексов. Требует значительной оперативной памяти для хранения хеш-таблицы.

3. Merge Join (Sort-Merge Join)

  • Принцип: Обе таблицы предварительно сортируются по ключу соединения. Затем происходит одновременное, последовательное сканирование обоих отсортированных наборов, как при слиянии.
  • Эффективность: Эффективен, если данные уже отсортированы или можно использовать индекс, предоставляющий порядок. Может быть дорогим из-за необходимости сортировки.

Ключевые отличия JOIN-типов:

  • INNER JOIN: Возвращает только строки, для которых есть совпадение в обеих таблицах. Несовпадающие строки отфильтровываются.
  • LEFT/RIGHT OUTER JOIN: Сохраняет все строки из одной таблицы (левой или правой). Если совпадения нет, для столбцов из другой таблицы подставляются NULL.
  • FULL OUTER JOIN: Сохраняет все строки из обеих таблиц, заполняя недостающие значения NULL.

На практике стоит использовать EXPLAIN (или EXPLAIN ANALYZE) для вашего конкретного запроса, чтобы увидеть, какой алгоритм выбрала СУБД.