0

[Database Design] Indexing: Từ "Tìm kim đáy bể" đến "Tốc độ ánh sáng"

1. Mở đầu: Câu chuyện về thư viện

Hãy tưởng tượng bạn bước vào một thư viện với 1 triệu cuốn sách nhưng các cuốn sách được xếp chồng lên nhau một cách ngẫu nhiên. Để tìm cuốn "Đắc Nhân Tâm", bạn phải kiểm tra từng cuốn một từ đầu đến cuối. Trong Database, đó gọi là Full Table Scan.

Nếu thư viện đó có một bộ thẻ tra cứu (catalog) được sắp xếp theo tên sách A-Z, bạn chỉ mất vài giây để biết cuốn sách nằm ở kệ nào. Đó chính xác là những gì Index làm cho cơ sở dữ liệu của bạn.

2. Index là gì? Bản chất của nó nằm ở đâu?

Về mặt kỹ thuật, Index (Chỉ mục) là một cấu trúc dữ liệu tách biệt với dữ liệu thực tế, được sử dụng để tăng tốc độ truy vấn.

Hầu hết các hệ quản trị CSDL (RDBMS) như MySQL, PostgreSQL hay SQL Server sử dụng cấu trúc B-Tree (Balanced Tree) để lưu trữ Index.

Tại sao lại là B-Tree?

  • Độ phức tạp: Thay vì O(n)O(n) như quét tuần tự, B-Tree giúp giảm xuống còn O(logn)O(\log n).
  • Cân bằng: Cây luôn cân bằng, đảm bảo thời gian tìm kiếm là ổn định cho mọi bản ghi.

3. Phân loại Index "phải biết"

Clustered Index (Chỉ mục cụm)

  • Quy định thứ tự vật lý của dữ liệu trên đĩa cứng.
  • Mỗi bảng chỉ có duy nhất 1 Clustered Index (thường là Primary Key).
  • Ví dụ: Danh bạ điện thoại sắp xếp theo tên người từ A-Z. Bản thân danh bạ chính là dữ liệu đã được sắp xếp.

Non-Clustered Index (Chỉ mục không cụm)

  • Dữ liệu nằm một nơi, chỉ mục nằm một nẻo. Chỉ mục chứa con trỏ (pointer) trỏ tới vị trí dữ liệu thực.
  • Bạn có thể tạo nhiều Non-Clustered Index trên một bảng.
  • Ví dụ: Mục lục ở cuối cuốn sách. Nó cho bạn biết từ khóa "Indexing" nằm ở trang 50, 120, 300.

4. "Con dao hai lưỡi" – Khi nào không nên Index?

Nhiều bạn nghĩ: "Cứ cột nào dùng trong WHERE thì Index hết cho nhanh". Sai lầm!

Indexing luôn đi kèm với cái giá của nó:

  • Tốn dung lượng: Index cần không gian lưu trữ riêng.
  • Chậm thao tác ghi (Write): Mỗi khi bạn INSERT, UPDATE hay DELETE, database phải cập nhật lại cả cây Index. Nếu có quá nhiều Index, hiệu năng ghi sẽ "tụt dốc không phanh".
  • Dữ liệu ít (Low Cardinality): Đừng Index cho những cột chỉ có vài giá trị lặp đi lặp lại (như giới tính: Nam/Nữ/Khác). Database sẽ thấy việc quét cả bảng còn nhanh hơn là tra Index.

Best Practices từ kinh nghiệm thực chiến

  1. Index các cột thường xuyên dùng trong JOIN, WHERE, ORDER BY.
  2. Sử dụng Composite Index (Index tổ hợp) đúng cách: Nếu bạn thường xuyên tìm kiếm theo HọTên, hãy tạo 1 Index trên cả 2 cột (last_name, first_name).

Lưu ý: Thứ tự cột trong Composite Index rất quan trọng (quy tắc tiền tố trái - Leftmost Prefix Rule).

  1. Tránh lạm dụng Function trong WHERE: WHERE YEAR(created_at) = 2023 sẽ làm Index bị "vô hiệu hóa".

Thay vào đó, hãy dùng: WHERE created_at >= '2023-01-01' AND created_at <= '2023-12-31'.

  1. Sử dụng EXPLAIN: Trước khi chốt một câu query, hãy chạy EXPLAIN để xem database có thực sự dùng Index mà bạn đã tạo hay không.

6. Kết luận

Indexing là một nghệ thuật cân bằng giữa Tốc độ đọcTốc độ ghi. Hiểu rõ bản chất của nó sẽ giúp hệ thống của bạn chịu tải tốt hơn và mang lại trải nghiệm mượt mà cho người dùng.

Hy vọng bài viết này giúp ích cho các bạn trong quá trình tối ưu hóa Database. Đừng quên Upvote và Follow mình để cập nhật thêm các kiến thức Backend bổ ích nhé!

Bạn có đang gặp vấn đề với một câu Query chạy chậm đến mức "rùa bò" không? Hãy comment bên dưới, mình sẽ cùng bạn phân tích và tìm ra cách đánh Index tối ưu nhất!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí