Trong khi truy xuất tất cả hoặc hầu hết các hàng từ một bảng, cách nhanh nhất cho loại truy vấn này thường là tổng hợp / phân biệt đầu tiên và tham gia sau :
SELECT *
FROM products p
JOIN (
SELECT DISTINCT ON (product_id) *
FROM meta
ORDER BY product_id, id DESC
) m ON m.product_id = p.id;
Các hàng khác trong meta
mỗi hàng trong products
, tác động đến hiệu suất càng lớn.
Tất nhiên, bạn sẽ muốn thêm ORDER BY
mệnh đề trong truy vấn con xác định which hàng để chọn từng bộ trong truy vấn con. @Craig và @Clodoaldo đã nói với bạn về điều đó. Tôi đang trả lại meta
hàng có id
cao nhất .
SQL Fiddle.
Chi tiết về DISTINCT ON
:
- Chọn hàng đầu tiên trong mỗi GROUP BY nhóm?
Tối ưu hóa hiệu suất
Tuy nhiên, đây không phải lúc nào cũng là giải pháp nhanh nhất. Tùy thuộc vào phân phối dữ liệu, có nhiều kiểu truy vấn khác nhau. Đối với trường hợp đơn giản này liên quan đến một phép nối khác, phép toán này chạy nhanh hơn đáng kể trong một bài kiểm tra với các bảng lớn:
SELECT p.*, sub.meta_id, m.product_id, m.price, m.flag
FROM (
SELECT product_id, max(id) AS meta_id
FROM meta
GROUP BY 1
) sub
JOIN meta m ON m.id = sub.meta_id
JOIN products p ON p.id = sub.product_id;
Nếu bạn không sử dụng id
không mô tả dưới dạng tên cột, chúng tôi sẽ không gặp va chạm khi đặt tên và có thể chỉ cần viết SELECT p.*, m.*
. (Tôi không bao giờ sử dụng id
dưới dạng tên cột.)
Nếu hiệu suất là yêu cầu tối quan trọng của bạn, hãy xem xét các tùy chọn khác:
- một
MATERIALIZED VIEW
với dữ liệu tổng hợp trước từmeta
, nếu dữ liệu của bạn không thay đổi (nhiều). - một CTE đệ quy mô phỏng quét chỉ mục lỏng lẻo cho một lớn
meta
bảng có nhiều hàng trên mỗi sản phẩm (tương đối ítproduct_id
riêng biệt ).
Đây là cách duy nhất tôi biết để sử dụng chỉ mục cho truy vấn DISTINCT trên toàn bộ bảng.