0Pricing
SQL Academy · Урок

Хеш-соединение, соединение слиянием и вложенный цикл

Познакомьтесь с тремя основными стратегиями соединения, их профилями стоимости и условиями, при которых планировщик выбирает каждую из них

«Хеш-соединение, соединение слиянием и вложенный цикл» — бесплатный урок SQL Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Academy содержит 4 уроков всего.

Три стратегии соединения

PostgreSQL использует три физических алгоритма соединения:

  • Вложенный цикл — для каждой внешней строки сканирует внутреннюю
  • Хеш-соединение — строит хеш-таблицу по внутренней стороне и выполняет поиск по ней с внешней
  • Соединение слиянием — обе стороны отсортированы и сливаются одновременно

Вложенный цикл

Простейший вариант: внешняя × внутренняя таблица. Быстро, когда у внутренней таблицы есть хороший индекс AND внешняя таблица мала:

EXPLAIN ANALYZE
SELECT * FROM users u JOIN orders o ON o.user_id = u.id
WHERE u.id = 42;
-- Nested Loop
--   -> Index Scan on users where id = 42  (rows=1)
--   -> Index Scan on orders_user_id_idx    (rows=5)

Когда вложенный цикл выигрывает

Во внешней части мало строк AND во внутренней есть индекс по ключу соединения — вложенный цикл чрезвычайно быстр. Худший случай: O(внешняя × внутренняя).

Хеш-соединение

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

EXPLAIN ANALYZE
SELECT * FROM big_a a JOIN big_b b ON a.key = b.key;
-- Hash Join (cost=10000..50000)
--   -> Seq Scan on big_a
--   -> Hash
--       -> Seq Scan on big_b

Когда хеш-соединение выигрывает

Две таблицы среднего или большого размера, отсутствие хорошего индекса по ключу соединения или необходимость получить много строк по оценке планировщика. Ограничение по памяти: хеш-таблица должна помещаться в work_mem, иначе она выгружается на диск.

Соединение слиянием

Обе стороны отсортированы по ключу соединения и проходят вместе. Отлично подходит, когда обе стороны уже отсортированы, например индексом с подходящим порядком:

EXPLAIN ANALYZE
SELECT * FROM big_a a JOIN big_b b ON a.key = b.key
ORDER BY a.key;
-- Merge Join
--   -> Index Scan on big_a (a.key ASC)
--   -> Index Scan on big_b (b.key ASC)

Когда соединение слиянием выигрывает

Два больших предварительно отсортированных набора входных данных. Линейное сканирование, небольшой расход памяти. Стоимость сортировки важна — если обе стороны нужно сортировать явно, хеш-соединение обычно выигрывает.

Выбор стратегии

Планировщик выбирает стратегию на основе:

  • Оценочного числа строк
  • Доступных индексов
  • Памяти (work_mem)
  • Констант стоимости в postgresql.conf

Принудительный выбор стратегии (только для диагностики)

Для отладки можно отключить стратегии:

SET enable_hashjoin = off;
SET enable_mergejoin = off;
SET enable_nestloop = off;
-- Re-run EXPLAIN to see what the planner picks instead.
-- NEVER persist these in production.

Выгрузка на диск

Если хеш-таблица или сортировка превышает work_mem, оператор выгружает временные файлы на диск — это намного медленнее. Либо увеличьте work_mem, либо перепишите запрос.

Параллельные соединения

PostgreSQL может выполнять хеш-соединение и соединение слиянием параллельно (а также последовательное сканирование и сканирование по индексу) — это видно по Parallel Hash Join с Workers Planned в EXPLAIN.

Как читать выбранную стратегию

В EXPLAIN ANALYZE имя узла соединения сообщает выбранную стратегию. Почти всегда выбор правилен — если это не так, сначала проверьте статистику и индексы, а уже потом принудительно задавайте стратегии.

Итоги

Три стратегии соединения подходят для разных ситуаций.

  • Вложенный цикл: небольшая внешняя часть + индексированная внутренняя
  • Хеш: большие таблицы, нет полезного индекса
  • Слияние: предварительно отсортированные входные данные

Быстрая проверка

Вы соединяете две таблицы по 10 миллионов строк по неиндексированному столбцу. Какой алгоритм соединения, скорее всего, выберет планировщик?

Часто задаваемые вопросы

Урок «Хеш-соединение, соединение слиянием и вложенный цикл» бесплатный?

Да — полный текст урока «Хеш-соединение, соединение слиянием и вложенный цикл» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Academy, подпишись на CoddyKit PRO. Курс SQL Academy содержит 4 уроков всего.

Чему я научусь в уроке «Хеш-соединение, соединение слиянием и вложенный цикл»?

Познакомьтесь с тремя основными стратегиями соединения, их профилями стоимости и условиями, при которых планировщик выбирает каждую из них Ты практикуешь SQL Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать SQL Academy?

Предыдущий опыт не требуется. SQL Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Хеш-соединение, соединение слиянием и вложенный цикл»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке SQL Academy?

Да. Каждый урок SQL Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Чтение EXPLAIN и EXPLAIN ANALYZE
  2. Последовательное сканирование и сканирование по индексу
  3. Хеш-соединение, соединение слиянием и вложенный цикл
  4. Поиск и исправление медленных запросов
← Назад к SQL Academy