Database Indexing 101 Cho Lập Trình Viên Laravel
Bạn tạo migration, deploy, và mọi thứ nhanh.
Sáu tháng sau, người dùng phàn nàn dashboard mất 10 giây để tải.
Bạn kiểm tra debugbar, và một câu SELECT * FROM orders WHERE user_id = 5 đơn giản mất 5 giây.
Bạn đã quên index.
Index Là Gì?
Hãy nghĩ về danh bạ điện thoại. Nếu bạn muốn tìm "Nguyễn", bạn không đọc từng tên từ A đến Z (Full Table Scan). Bạn nhảy đến "N". Cách triển khai đó là B-Tree Index.
Cách Thêm Index Trong Laravel
Một Cột:
$table->string('email')->index();
// HOẶC
$table->index('email');
Index Kết Hợp (Nhiều Cột):
Nếu bạn thường xuyên query theo hai cột cùng lúc:
WHERE status = 'active' AND type = 'premium'
$table->index(['status', 'type']);
Thứ Tự Quan Trọng!
Trong index kết hợp (status, type), database sắp xếp theo status trước, sau đó type.
- Query
WHERE status = 'active'-> Sử Dụng Index. - Query
WHERE type = 'premium'-> KHÔNG sử dụng Index (thường thì vậy).
Luôn đặt cột bạn query nghiêm ngặt nhất (cardinality cao nhất) lên đầu.
Foreign Key
Laravel tự động tạo index cho Foreign Key? KHÔNG, KHÔNG HỀ.
$table->foreignId('user_id')->constrained();
// Điều này tạo constraint check, nhưng dựa vào index.
// Hầu hết DB engine tự động index FK, nhưng index tường minh an toàn hơn.
Khi Nào KHÔNG Nên Index?
- Cardinality Thấp: Cột
gender(Nam/Nữ). DB phải scan 50% bảng dù sao. - Bảng Ghi Nhiều: Mỗi lần bạn
INSERThoặcUPDATE, DB phải cập nhật index. Quá nhiều index làm chậm việc ghi.
Debug
Chạy EXPLAIN select * from users where ... trong SQL client của bạn. Nếu type hiện ALL, bạn đang thực hiện full table scan.