Có Index chưa chắc Query nhanh
Hiểu lầm phổ biến nhất: “tôi đã tạo index rồi mà vẫn chậm”. Dùng index không đảm bảo query nhanh - phải hiểu quy trình 4 bước thực tế.
Quy trình khi database dùng index
1. Tìm matching entries trong index ← Index giúp bước này nhanh
↓ (danh sách row IDs / PK values)
2. Load từng row từ table (random I/O) ← CHẬM nếu quá nhiều row!
↓
3. Check thêm các điều kiện KHÔNG ← Lãng phí nếu nhiều row bị loại
nằm trong index
↓
4. Trả kết quảBước 2 và 3 chính là nơi query chậm.
Ví dụ thực tế
-- Bảng orders: 5 triệu rows. Index: chỉ có trên (status)
SELECT * FROM orders
WHERE status = 'pending' -- index lọc: 5M → 200,000 rows
AND region = 'southeast' -- KHÔNG trong index
AND total > 1000000; -- KHÔNG trong index
-- 1. Index tìm 200,000 entries có status='pending' ← nhanh
-- 2. Load 200,000 rows từ table (random I/O) ← CHẬM!
-- 3. Check region → còn 15,000 (lãng phí 185,000 lần đọc)
-- 4. Check total → còn 500 (lãng phí thêm 14,500 lần)
-- Kết quả: chỉ cần 500 rows nhưng đã load 200,000 rows!Giải pháp
Tạo index bao phủ nhiều điều kiện hơn:
-- Index tốt hơn: (status, region, total)
-- 1. status = 'pending' → fast lookup
-- 2. region = 'southeast' → tiếp tục lọc TRONG index (không cần load row)
-- 3. total > 1000000 → scan range trên index
-- 4. Chỉ load ~500 rows thực sự cần
-- Hoặc index-only nếu chỉ cần vài cột:
-- (status, region, total) INCLUDE (order_id, customer_id)Quy tắc thực hành
Sau khi tạo index, luôn chạy EXPLAIN để xác nhận database thực sự dùng index, và kiểm tra số row phải load (rows examined/filtered). Nếu rows examined >> rows trả về → index chưa đủ tốt.
Liên quan
- Random IO vs Sequential IO - vì sao bước 2 đắt
- Composite Index và Nguyên tắc Phễu - cách thiết kế index bao phủ
- Index-Only Query và Covering Index - loại bỏ hoàn toàn bước 2
- Query Optimizer và Cost Model - vì sao đôi khi DB bỏ luôn index