Sự nhầm lẫn xung quanh LEFT JOIN
và WHERE
điều khoản đã được làm rõ nhiều lần:
Câu hỏi thú vị này còn lại:
Không có gợi ý truy vấn rõ ràng nào trong Postgres. (Đây là một vấn đề đang được tranh luận.) Nhưng vẫn có nhiều thủ thuật khác nhau để khiến Postgres phải đi theo con đường của bạn.
Nhưng trước tiên, hãy tự hỏi bản thân: Tại sao người lập kế hoạch truy vấn lại ước tính kế hoạch đã chọn sẽ rẻ hơn khi bắt đầu? Cấu hình máy chủ của bạn về cơ bản có tốt không? Cài đặt chi phí phù hợp? autovacuum
đang chạy? Phiên bản Postgres đã lỗi thời? Bạn có đang giải quyết một vấn đề cơ bản cần được khắc phục không?
Nếu bạn buộc Postgres làm theo cách của bạn, bạn nên chắc chắn rằng nó sẽ không kích hoạt trở lại, sau khi nâng cấp phiên bản hoặc cập nhật cấu hình máy chủ ... Bạn nên biết chính xác những gì bạn đang làm.
Điều đó nói rằng, bạn có thể buộc Postgres phải "lọc ra một số bản ghi trước khi thực hiện JOIN
" với một truy vấn con nơi bạn thêm OFFSET 0
- về mặt logic, đó chỉ là tiếng ồn, nhưng ngăn không cho Postgres sắp xếp lại nó thành dạng liên kết thông thường. (Rốt cuộc là gợi ý truy vấn)
SELECT la.listing_id, la.id, lar.*
FROM (
SELECT listing_id, id
FROM la
WHERE listing_id = 2780
OFFSET 0
) la
LEFT JOIN lar ON lar.application_id = la.id;
Hoặc bạn có thể sử dụng CTE (ít tối nghĩa, nhưng đắt hơn). Hoặc các thủ thuật khác như thiết lập các thông số cấu hình nhất định. Hoặc, trong trường hợp cụ thể này, Tôi sẽ sử dụng LATERAL
tham gia cùng một hiệu ứng:
SELECT la.listing_id, la.id, lar.*
FROM la
LEFT JOIN LATERAL (
SELECT *
FROM lar
WHERE application_id = la.id
) lar ON true
WHERE la.listing_id = 2780;
Có liên quan:
Đây là một blog mở rộng về gợi ý Truy vấn của 2ndQuadrant. Năm tuổi nhưng vẫn còn giá trị.