PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

GROUP hoặc DISTINCT sau khi JOIN trả về các bản sao

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 ít product_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.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bắt đầu và điền vùng chứa Postgres trong Docker

  2. Cách Mod () hoạt động trong PostgreSQL

  3. SQLAlchemy không có mật khẩu được cung cấp lỗi

  4. pghoard Alternatives - Quản lý sao lưu PostgreSQL với ClusterControl

  5. Mệnh đề KIỂM TRA cho các chế độ xem có thể cập nhật