Методы формирования соединений наборов строк
Вложенный цикл (nested loop)
demo=# EXPLAIN SELECT a.aircraft_code, a.model, s.seat_no, s.fare_conditions
demo-# FROM bookings.seats s
demo-# JOIN bookings.aircrafts a ON s.aircraft_code = a.aircraft_code
demo-# WHERE a.model ~ '^Air'
demo-# ORDER BY s.seat_no ;
QUERY PLAN
---------------------------------------------------------------------------------------
Sort (cost=23.28..23.65 rows=149 width=59)
Sort Key: s.seat_no
-> Nested Loop (cost=5.43..17.90 rows=149 width=59)
-> Seq Scan on aircrafts a (cost=0.00..1.11 rows=1 width=48)
Filter: (model ~ '^Air'::text)
-> Bitmap Heap Scan on seats s (cost=5.43..15.29 rows=149 width=15)
Recheck Cond: (aircraft_code = a.aircraft_code)
-> Bitmap Index Scan on seats_pkey (cost=0.00..5.39 rows=149 width=0)
Index Cond: (aircraft_code = a.aircraft_code)
(9 rows)
Nested Loop - узел в котором выполняется соединение, имеет два дочерних узла: Seq Scan ( внешний узел ) и Bitmap Heap Scan ( внутренний узел )
Во внешнем узле последовательно сканируется таблица aircrafts ( JOIN ) согласно условию WHERE Filter: (model ~ '^Air'::text)
Для каждой из отобранных строк из aircrafts выполняется поиск в таблице seats по индексу с использованием битовой карты в узле Bitmap Heap Scan
[200~Recheck Cond: (aircraft_code = a.aircraft_code)
На самом верхнем узле, строики сортируются по ключу: s.seat_no
соединение хешированием (hash join)
demo=# EXPLAIN SELECT r.flight_no, r.departure_airport_name, r.arrival_airport_name, a.model
FROM bookings.routes r
JOIN bookings.aircrafts a ON r.aircraft_code = a.aircraft_code
ORDER BY flight_no ;
QUERY PLAN
------------------------------------------------------------------------------
Sort (cost=61.67..63.44 rows=710 width=75)
Sort Key: r.flight_no
-> Hash Join (cost=1.20..28.05 rows=710 width=75)
Hash Cond: (r.aircraft_code = a.aircraft_code)
-> Seq Scan on routes r (cost=0.00..24.10 rows=710 width=47)
-> Hash (cost=1.09..1.09 rows=9 width=48)
-> Seq Scan on aircrafts a (cost=0.00..1.09 rows=9 width=48)
(7 rows)
На самом нижнем уровне последовательно сканируется таблица aircrafts и формируется hash-таблица, ключами которой являются значения атрибута aircraft_code, по нему выполняется соединение таблиц
Hash-таблица формируется на основе той таблицы, в которой число строк для перебора меньше
Также последовательно сканируется таблица routes и для каждой ее строки выполняется поиск соответствия значения среди ключей хеш таблицы:
Hash Cond: (r.aircraft_code = a.aircraft_code)
Таким образом формируется результирующая строка при совпадении
соединение слиянием (merge join)
demo=# EXPLAIN SELECT t.ticket_no, t.passenger_name, tf.flight_id, tf.amount
FROM bookings.tickets t
JOIN bookings.ticket_flights tf ON t.ticket_no = tf.ticket_no
ORDER BY t.ticket_no ;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------
Merge Join (cost=0.99..822424.45 rows=8391852 width=40)
Merge Cond: (t.ticket_no = tf.ticket_no)
-> Index Scan using tickets_pkey on tickets t (cost=0.43..139110.29 rows=2949857 width=30)
-> Index Scan using ticket_flights_pkey on ticket_flights tf (cost=0.56..571041.37 rows=8391852 width=24)
JIT:
Functions: 7
Options: Inlining true, Optimization true, Expressions true, Deforming true
(7 rows)
Два нижних узла сканируют таблицы
Верхний узел Join получает наборы строк этих таблиц в сортированном виде, слияние происходит по значениям атрибута ticket_no
Источники
Связанные темы
Оптимизация запросов в Postgresql
Установка и настройка MS SQL Server 2008 на Windows Server 2008 r
Системный каталог в Postgresql
Табличные пространства в Postgresql
Определение данных в Postgresql
Изменение временной зоны в Postgresql
Основные команды psql и sql Postgresql
Агрегирование и группировка в Postgresql