Site logo

Tối Ưu Query MySQL Với Index: Từ Cơ Bản Đến Nâng Cao

5:00 read

Giới Thiệu

Bài trước (Index trong MySQL: Hướng dẫn toàn diện từ cơ bản đến nâng cao) đã giải thích index là gì, có những loại index nào. Bài này đi xa hơn một bước: có index rồi mà query vẫn chậm thì phải làm sao?

Đây là tình huống rất phổ biến trong thực tế: bảng có index, câu query "nhìn qua thì ổn", nhưng khi dữ liệu lớn dần (vài chục nghìn đến vài triệu dòng), một API vốn chạy dưới 1 giây bỗng chạy 10-15 giây, thậm chí timeout. Phần lớn nguyên nhân không phải "thiếu index" theo nghĩa chung chung, mà là:

  • Index có nhưng sai cột, sai thứ tự cột.
  • Query dùng đúng index nhưng MySQL chỉ dùng được một phần của nó (leftmost prefix bị cắt ngang).
  • Có những đoạn SQL tưởng vô hại (subquery lồng trong SELECT, hàm áp lên cột) âm thầm vô hiệu hoá index.

Bài viết này sẽ đi theo đúng quy trình một kỹ sư backend thực sự làm khi nhận ticket "API này chậm quá": đo trước, đọc EXPLAIN, tìm đúng điểm nghẽn, sửa, đo lại để chứng minh. Toàn bộ case study ở cuối bài là một tình huống có thật, đã được đo bằng số liệu thực, chỉ đổi tên bảng/cột sang tên chuẩn phổ biến để dễ áp dụng vào dự án của bạn.

Tại Sao Query Chậm Dù Đã Có Index?

Một sai lầm phổ biến của người mới là nghĩ "có index là nhanh". Thực tế, MySQL Optimizer chỉ dùng index khi:

  1. Cột lọc/join/sắp xếp nằm trong index, đúng thứ tự cần thiết.
  2. Kiểu dữ liệu khớp nhau giữa cột và giá trị so sánh.
  3. Điều kiện không bị bọc trong hàm/biểu thức làm cột (CAST(), DATE_FORMAT(), LOWER()...).
  4. Optimizer ước tính dùng index sẽ rẻ hơn quét toàn bảng (đôi khi optimizer đoán sai, gọi là "cardinality estimation error").

Chỉ cần vi phạm một trong 4 điều trên, index coi như "vô hình" — MySQL vẫn có thể chạy ra kết quả đúng, nhưng phải quét nhiều hơn cần thiết. Đây là lý do một query "trông có index" vẫn chậm.

Yêu cầu đăng nhập

Vui lòng đăng nhập để truy cập nội dung này

Additional Resources

Course Guide

Comprehensive PDF guide with examples

GitHub Repository

Example code for all lessons

Discussion

Have a question about this lesson? Post it here and get answers from instructors and peers.