Partial Index (chỉ PostgreSQL)
Thay vì đánh index toàn bộ bảng, chỉ đánh index cho những dòng bạn quan tâm. Giải pháp đẹp nhất cho cột ít giá trị phân biệt.
-- Chỉ index những dòng có is_processed = FALSE
CREATE INDEX orders_unprocessed
ON orders (created_at)
WHERE is_processed = FALSE;Hình dung sự khác biệt
Index thông thường trên (is_processed):
→ Chứa 1,000,000 entry (toàn bộ bảng), ~30 MB
→ Database thường bỏ qua vì quá nhiều kết quả khớp
Partial index WHERE is_processed = FALSE:
→ Chỉ chứa 200,000 entry (phần chưa xử lý), ~6 MB
→ Được sắp xếp theo created_at → lấy theo thời gian cực nhanh
→ Khi dữ liệu được xử lý xong, entry TỰ BIẾN MẤT khỏi index-- PostgreSQL tự nhận diện khi WHERE của query khớp WHERE của index:
SELECT * FROM orders
WHERE is_processed = FALSE
ORDER BY created_at
LIMIT 100;
-- → Dùng partial index, cực nhanh dù bảng có hàng triệu dòngQuy tắc nhớ
Chỉ đánh index cột boolean/trạng thái khi tìm kiếm giá trị hiếm (dưới vài phần trăm tổng số dòng). Với PostgreSQL, ưu tiên partial index: nhỏ hơn, nhanh hơn, và tự “thu gọn” khi dữ liệu thay đổi.
MySQL không hỗ trợ partial index - cân nhắc index thường trên cột trạng thái + query giá trị hiếm, hoặc thiết kế khác.
Liên quan
- Low-Cardinality Column và Index - vấn đề mà partial index giải quyết
- Index Write Overhead - partial index còn giảm chi phí ghi (chỉ update khi row match WHERE)
- Random IO vs Sequential IO - vì sao index nhỏ + ít kết quả = thắng