Hash Join vs Hash Semi Join


8

PostgreSQL 9.2

ฉันพยายามที่จะเข้าใจความแตกต่างระหว่างและเพียงแค่Hash Semi JoinHash Join

นี่คือสองคำค้นหา:

ผม

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

ครั้งที่สอง

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

ที่สามารถมองเห็นความแตกต่างเฉพาะในแผนก็คือว่าในกรณีแรกที่กิน hastable 7kBแต่ในครั้งที่สองและที่โหนดคือ37kBHash Semi Join

แต่ฉันไม่เข้าใจความแตกต่างในขนาดของ hashtable Hashโหนดใช้อย่างสมบูรณ์แบบเดียวกันโหนดมีเดียวกันSeq Scan Filterทำไมถึงมีความแตกต่าง


คุณดูผลลัพธ์ของแบบสอบถามจริงหรือไม่ explain (analyze, verbose)หรือใช้
jjanes

คำตอบ:


5

ในแบบสอบถามแรกเฉพาะ customer_id เท่านั้นที่จะต้องบันทึกจากcustomersในตารางแฮชเพราะนั่นเป็นข้อมูลเพียงอย่างเดียวที่ต้องใช้ในการเข้าร่วมกึ่ง

ในแบบสอบถามที่สองคอลัมน์ทั้งหมดจะต้องเก็บไว้ในตารางแฮชเนื่องจากคุณกำลังเลือกคอลัมน์ทั้งหมดจากตาราง (โดยใช้*) แทนที่จะต้องทดสอบการมีอยู่ของ customer_id

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.