Hash Tham gia vs Hash Semi Tham gia


8

PostgreQuery 9.2

Tôi đang cố gắng để hiểu sự khác biệt giữa Hash Semi Joinvà chỉ Hash Join.

Đây là hai truy vấn:

Tôi

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

Có thể thấy, sự khác biệt duy nhất trong các kế hoạch là trong trường hợp đầu tiên, mức tiêu thụ nhanh 7kB, nhưng trong lần thứ hai 37kBvà nút đó là Hash Semi Join.

Nhưng tôi không hiểu sự khác biệt trong kích thước hashtable. Các Hashnút sử dụng một cách hoàn hảo cùng Seq Scannút có cùng Filter. Tại sao có sự khác biệt?


Bạn đã nhìn vào đầu ra thực tế của các truy vấn? Hoặc, sử dụng explain (analyze, verbose).
jjanes

Câu trả lời:


5

Trong truy vấn đầu tiên, chỉ cần lưu khách hàng_id từ customersbảng băm, vì đó là dữ liệu duy nhất cần thiết để thực hiện bán tham gia.

Trong truy vấn thứ hai, tất cả các cột cần được lưu trữ vào bảng băm, bởi vì bạn đang chọn tất cả các cột từ bảng (sử dụng *) thay vì chỉ kiểm tra sự tồn tại của customer_id.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.