PostgreSQL 9.2
Ich versuche den Unterschied zwischen Hash Semi Join
und gerecht zu verstehen Hash Join
.
Hier sind zwei Fragen:
ich
EXPLAIN ANALYZE SELECT * FROM orders WHERE customerid IN (SELECT
customerid FROM customers WHERE state='MD');
Hash Semi Join (cost=740.34..994.61 rows=249 width=30) (actual time=2.684..4.520 rows=120 loops=1)
Hash Cond: (orders.customerid = customers.customerid)
-> Seq Scan on orders (cost=0.00..220.00 rows=12000 width=30) (actual time=0.004..0.743 rows=12000 loops=1)
-> Hash (cost=738.00..738.00 rows=187 width=4) (actual time=2.664..2.664 rows=187 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 7kB
-> Seq Scan on customers (cost=0.00..738.00 rows=187 width=4) (actual time=0.018..2.638 rows=187 loops=1)
Filter: ((state)::text = 'MD'::text)
Rows Removed by Filter: 19813
II
EXPLAIN ANALYZE SELECT * FROM orders o JOIN customers c ON o.customerid = c.customerid WHERE c.state = 'MD'
Hash Join (cost=740.34..1006.46 rows=112 width=298) (actual time=2.831..4.762 rows=120 loops=1)
Hash Cond: (o.customerid = c.customerid)
-> Seq Scan on orders o (cost=0.00..220.00 rows=12000 width=30) (actual time=0.004..0.768 rows=12000 loops=1)
-> Hash (cost=738.00..738.00 rows=187 width=268) (actual time=2.807..2.807 rows=187 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 37kB
-> Seq Scan on customers c (cost=0.00..738.00 rows=187 width=268) (actual time=0.018..2.777 rows=187 loops=1)
Filter: ((state)::text = 'MD'::text)
Rows Removed by Filter: 19813
Wie zu sehen ist, besteht der einzige Unterschied in den Plänen darin, dass im ersten Fall das Hastable verbraucht 7kB
, im zweiten Fall jedoch 37kB
der Knoten Hash Semi Join
.
Aber ich verstehe den Unterschied in der Größe der Hashtabelle nicht. Der Hash
Knoten verwendet perfekt denselben Seq Scan
Knoten mit demselben Filter
. Warum gibt es den Unterschied?
postgresql
join
hashing
St.Antario
quelle
quelle
explain (analyze, verbose)
.Antworten:
In der ersten Abfrage muss nur die customer_id aus der
customers
Hash-Tabelle gespeichert werden , da dies die einzigen Daten sind, die zum Implementieren des Semi-Joins benötigt werden.In der zweiten Abfrage müssen alle Spalten in der Hash-Tabelle gespeichert werden, da Sie alle Spalten aus der Tabelle auswählen (mit
*
) und nicht nur die Existenz der customer_id testen.quelle