Nhiều người nghĩ rằng có Index là query sẽ nhanh. Nhưng thực tế, MySQL vẫn phải thực hiện một thao tác rất tốn kém gọi là Row Lookup (tìm vào file dữ liệu thật) sau khi đã tìm thấy ID trong Index. Covering Index sinh ra để loại bỏ hoàn toàn bước này.
#1. Bản chất: Index-only Scan
Thông thường, quy trình là: Tìm trong Index -> Lấy địa chỉ hàng -> Tìm vào Table lấy dữ liệu các cột khác.
Covering Index là một Index chứa TẤT CẢ các cột mà câu query yêu cầu (SELECT, WHERE, ORDER BY). Khi đó, MySQL thấy dữ liệu đã có sẵn trong Index (nằm trên RAM) nên trả về kết quả luôn.
#2. Ví dụ thực tế
Giả sử bạn có bảng orders (10 triệu record) và câu query:
SELECT status, updated_at FROM orders WHERE user_id = 5;
- Cách 1 (Tệ): Index trên
user_id. MySQL tìm thấyuser_id=5, sau đó phải “nhảy” vào bảng chính để lấystatusvàupdated_at. - Cách 2 (Covering): Tạo Composite Index trên
(user_id, status, updated_at). MySQL lấy được mọi thứ ngay trong Index.
#3. Tại sao nó lại nhanh kinh khủng?
- Giảm Disk I/O: Dữ liệu Index thường nhỏ và nằm gọn trong RAM (Buffer Pool). Dữ liệu Table thường nằm trên SSD/HDD.
- Dữ liệu tập trung: Các node trong Index B-Tree nằm cạnh nhau, giúp việc đọc tuần tự cực nhanh.
#4.Câu hỏi nhanh
Câu hỏi: Làm thế nào để biết một câu query đang sử dụng Covering Index khi dùng lệnh EXPLAIN?
Trả lời:
Hãy nhìn vào cột Extra trong kết quả trả về của EXPLAIN. Nếu bạn thấy dòng chữ “Using index” (đừng nhầm với “Using where”), điều đó có nghĩa là MySQL đang sử dụng Covering Index và không cần truy cập vào file dữ liệu thực tế.
Câu hỏi mẹo: Có nên biến mọi Index thành Covering Index bằng cách thêm thật nhiều cột vào không? Trả lời: Tuyệt đối không.
- Thứ nhất: Index quá to sẽ chiếm dụng RAM Buffer Pool, đẩy các dữ liệu quan trọng khác ra ngoài.
- Thứ hai: Mỗi khi
INSERT/UPDATE/DELETE, MySQL phải cập nhật lại tất cả các cột trong Index, làm chậm thao tác Ghi (Write) một cách đáng kể. Chiến lược: Chỉ dùng Covering Index cho các query cực kỳ thường xuyên và có yêu cầu độ trễ (latency) cực thấp.
#5. Kết luận
Covering Index là một “vũ khí hạng nặng” trong tối ưu hóa Database. Hãy dùng nó một cách chọn lọc để biến những câu query hàng giây thành hàng mili giây.