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