Index Selection - Xung đột giữa Lọc và Sắp xếp
Khi có nhiều index, database phải CHỌN - và đôi khi chọn khác kỳ vọng của bạn.
Nhiều điều kiện + nhiều index đơn lẻ
-- Query: WHERE firstname = 'Huy' AND lastname = 'Nguyen'
-- Index A: (firstname) → ước tính match 500 rows
-- Index B: (lastname) → ước tính match 200 rows
-- Database chọn Index B vì 200 < 500 → ít row phải load hơn
-- ✅ Giải pháp tốt nhất: composite index (firstname, lastname)
-- → chỉ match đúng số row cần thiếtTình huống “tiến thoái lưỡng nan” kinh điển: Filter vs Sort
SELECT * FROM issues
WHERE type = 'open' ORDER BY created_at DESC LIMIT 10;Plan A: Dùng index (type)
1. Tìm tất cả issues type='open' → 50,000 rows
2. Sort 50,000 rows theo created_at DESC ← chậm ở bước sort
3. Lấy top 10
Plan B: Dùng index (created_at DESC)
1. Scan từ created_at mới nhất
2. Với mỗi row, check type='open', đủ 10 rows → dừng
→ Nếu issues open PHỔ BIẾN: chỉ scan ~15-20 rows → CỰC NHANH
→ Nếu issues open HIẾM: phải scan hàng nghìn rows → CHẬM
Plan C: Index (type, created_at DESC) ← GIẢI PHÁP TỐT NHẤT
1. Fast lookup type='open'
2. Scan 10 entries theo created_at DESC → Xong!
→ Luôn nhanh, BẤT KỂ phân phối dữ liệuBài học: Khi query có cả WHERE và ORDER BY, index tốt nhất bao gồm cả hai - cột filter trước, cột sort sau.
Liên quan
- ORDER BY và Index - tránh sort bổ sung
- Query Optimizer và Cost Model - cách DB so chi phí giữa các plan
- Statistics và ANALYZE - ước tính số row match dựa vào thống kê
- Composite Index và Nguyên tắc Phễu