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

Tối ưu hóa truy vấn tối đa theo nhóm

Giả sử tương đối ít hàng trong options cho nhiều hàng trong records .

Thông thường, bạn sẽ có một bảng options tra cứu được tham chiếu từ records.option_id , lý tưởng là với ràng buộc khóa ngoại. Nếu bạn không, tôi khuyên bạn nên tạo một cái để thực thi tính toàn vẹn của tham chiếu:

CREATE TABLE options (
  option_id int  PRIMARY KEY
, option    text UNIQUE NOT NULL
);

INSERT INTO options
SELECT DISTINCT option_id, 'option' || option_id -- dummy option names
FROM   records;

Sau đó, không cần phải mô phỏng quét chỉ mục lỏng lẻo nữa và việc này trở nên rất đơn giản và nhanh chóng . Các truy vấn con có liên quan có thể sử dụng một chỉ mục đơn giản trên (option_id, id) .

SELECT option_id, (SELECT max(id)
                   FROM   records
                   WHERE  option_id = o.option_id) AS max_id
FROM   options o
ORDER  BY 1;

Điều này bao gồm các tùy chọn không khớp trong bảng records . Bạn nhận được NULL cho max_id và bạn có thể dễ dàng xóa các hàng như vậy trong SELECT bên ngoài nếu cần.

Hoặc (cùng một kết quả):

SELECT option_id, (SELECT id
                   FROM   records
                   WHERE  option_id = o.option_id
                   ORDER  BY id DESC NULLS LAST
                   LIMIT  1) AS max_id
FROM   options o
ORDER  BY 1;

Có thể nhanh hơn một chút. Truy vấn con sử dụng thứ tự sắp xếp DESC NULLS LAST - giống như hàm tổng hợp max() mà bỏ qua các giá trị NULL. Chỉ sắp xếp DESC sẽ có NULL đầu tiên:

  • Tại sao các giá trị NULL lại xuất hiện đầu tiên khi đặt hàng DESC trong một truy vấn PostgreSQL?

Chỉ số hoàn hảo cho việc này:

CREATE INDEX on records (option_id, id DESC NULLS LAST);

Thứ tự sắp xếp chỉ mục không quan trọng lắm trong khi các cột được xác định NOT NULL .

Vẫn có thể quét tuần tự trên bảng nhỏ options , đó chỉ là cách nhanh nhất để tìm nạp tất cả các hàng. ORDER BY có thể mang lại một bản quét chỉ mục (chỉ) để tìm nạp các hàng được sắp xếp trước.
Bảng lớn records chỉ được truy cập thông qua quét chỉ mục (bitmap) hoặc, nếu có thể, quét chỉ chỉ mục .

db <> fiddle here - hiển thị hai bản quét chỉ lập chỉ mục cho trường hợp đơn giản
Old sqlfiddle

Hoặc sử dụng LATERAL tham gia để có hiệu ứng tương tự trong Postgres 9.3+:

  • Tối ưu hóa truy vấn GROUP BY để truy xuất hàng mới nhất cho mỗi người dù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. lưu trữ các chuỗi có độ dài tùy ý trong Postgresql

  2. Tạo n hàng NULL trong PostgreSQL

  3. Cách không tạo tiện ích mở rộng PostgreSQL 9.0 trên nền tảng RPM

  4. CHÈN các hàng vào nhiều bảng trong một truy vấn, chọn từ một bảng có liên quan

  5. Duy trì múi giờ ở loại timestamptz PostgreSQL