Trong quá trình xây dựng hệ thống, bạn có thể tạo ra một cơ sở dữ liệu “chạy được”, nhưng liệu nó có chạy nhanh không là một câu chuyện khác. Những hệ thống lớn thường có hàng ngàn đến hàng triệu bản ghi, nếu không tối ưu truy vấn ngay từ đầu thì sau này sẽ rất dễ rơi vào tình trạng giật lag, tải chậm, hoặc timeout.
Ở bài học này, bạn sẽ được hướng dẫn các kỹ thuật căn bản để tối ưu truy vấn SQL, cụ thể là:
- Khi nào cần sử dụng index
- Những kiểu SELECT nên tránh hoặc thay thế
- Một số mẹo nhỏ nhưng cực kỳ hiệu quả
Tối ưu bằng Index – đừng chờ đến khi chậm mới tạo
Index là gì?
Index (chỉ mục) giống như mục lục trong sách – giúp bạn tra nhanh thông tin cần tìm. Khi không có index, MySQL phải duyệt từng dòng trong bảng → rất tốn thời gian với bảng lớn.
Khi nào nên dùng Index?
Dùng Index khi cột đó thường xuyên:
- Được dùng trong
WHERE
,JOIN
,ORDER BY
,GROUP BY
- Có giá trị phân biệt cao (ví dụ: ID người dùng, email, mã sản phẩm)
Không nên dùng Index khi:
- Cột có giá trị lặp lại quá nhiều (ví dụ: cột
giới_tính
chỉ có “Nam”, “Nữ”) - Bảng quá nhỏ (vì chi phí tạo và duy trì index cao hơn lợi ích)
Cách thêm Index?
CREATE INDEX idx_user_email ON users(email);
Hoặc khi tạo bảng:
CREATE TABLE users (
id INT PRIMARY KEY,
email VARCHAR(255),
INDEX(email)
);
Tránh dùng SELECT “tham lam”
Tránh SELECT *
Khi bạn viết:
SELECT * FROM users;
MySQL sẽ phải tải tất cả các cột, kể cả những cột bạn không cần dùng, gây nặng cho bộ nhớ và làm chậm tốc độ.
Thay vì thế, hãy chỉ chọn những cột cần thiết:
SELECT name, email FROM users;
Giới hạn kết quả với LIMIT
Không nên trả về hàng ngàn kết quả nếu bạn chỉ cần 10 bản ghi:
SELECT * FROM posts ORDER BY created_at DESC LIMIT 10;
Tránh truy vấn lồng nhau không cần thiết
Hạn chế việc lồng SELECT như sau:
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders);
Hãy thay bằng JOIN nếu có thể:
SELECT DISTINCT users.*
FROM users
JOIN orders ON users.id = orders.user_id;
Kiểm tra hiệu năng bằng EXPLAIN
Bạn có thể dùng EXPLAIN
để kiểm tra xem truy vấn có dùng index không:
EXPLAIN SELECT name FROM users WHERE email = 'abc@example.com';
Nếu trong kết quả có dòng key: email
, nghĩa là index đang hoạt động.
Một số mẹo nhỏ đáng nhớ
- Đặt index vào những cột lọc nhiều nhất
- Dọn dẹp dữ liệu cũ nếu không còn sử dụng
- Tránh JOIN nhiều bảng nếu không cần thiết
- Hạn chế dùng
LIKE '%abc%'
→ MySQL không dùng được index
Tổng kết
Tối ưu SQL là việc cần làm thường xuyên, ngay cả khi bạn đang ở giai đoạn phát triển ban đầu. Việc sử dụng đúng Index và viết truy vấn gọn gàng, có chủ đích sẽ giúp hệ thống chạy trơn tru, tiết kiệm tài nguyên và phản hồi nhanh hơn rất nhiều.
Trong bài tiếp theo, chúng ta sẽ tổng kết lại toàn bộ chương 4 và thực hành một ví dụ thực tế: phân tích và thiết kế hệ thống Blog chuẩn hóa và tối ưu.
Thảo luận