Lập chỉ mục (Indexing)
Một chỉ mục (index) giống như mục lục ở cuối một cuốn sách: nó cho phép cơ sở dữ liệu nhảy thẳng đến các dòng phù hợp thay vì quét qua từng dòng một. Không có chỉ mục, các truy vấn sẽ chậm dần khi dữ liệu tăng lên — ổn ở 100 dòng, đau đớn ở 1.000.000 dòng.
Không có chỉ mục, cơ sở dữ liệu kiểm tra từng dòng một; có chỉ mục, nó nhảy thẳng đến chỗ khớp, giống như mục lục sách đưa bạn đến đúng trang thay vì đọc từ đầu đến cuối:
NO INDEX (Seq Scan) WITH INDEX (Index Scan)
read EVERY row, one by one jump straight to matches
┌─────────────────────┐ ┌─────────────┐
│ row 1 ✗ │ │ INDEX │
│ row 2 ✗ │ │ author_id │
│ row 3 ✓ match │ ◀──────┐ │ ──┬── │
│ row 4 ✗ │ │ └─────┼───────┘
│ ... (1,000,000) │ │ ▼
│ row N ✓ match │ └──▶ rows 3, 998 ✓
└─────────────────────┘ a few hops, not a million
Hướng dẫn thực tế:
- Lập chỉ mục cho các cột bạn thường xuyên lọc (filter) hoặc nối (join) (ví dụ
author_id,email). - Khóa chính được tự động lập chỉ mục.
- Đừng lập chỉ mục cho mọi thứ — mỗi chỉ mục làm tăng tốc độ đọc nhưng làm chậm việc ghi và tốn thêm dung lượng.
- Chỉ thêm chỉ mục khi bạn thấy một truy vấn chậm, không phải lập sẵn cho mọi cột từ trước.
Cách trung thực để biết một chỉ mục có giúp ích hay không là hỏi cơ sở dữ liệu, chứ không phải đoán mò. Mọi bộ máy đều có EXPLAIN (trong Postgres là EXPLAIN ANALYZE), lệnh này cho thấy kế hoạch thực thi mà nó sẽ dùng:
EXPLAIN ANALYZE
SELECT * FROM posts WHERE author_id = '...';
Nếu kết quả trả về nói Seq Scan trên một bảng lớn, nghĩa là cơ sở dữ liệu đang đọc từng dòng một — dấu hiệu cho thấy một chỉ mục sẽ có ích. Sau khi thêm chỉ mục, nó nên chuyển sang Index Scan. Đây là một việc tuyệt vời để giao cho AI: dán truy vấn chậm và kết quả EXPLAIN, rồi hỏi nên thêm chỉ mục nào và tại sao. Bạn vẫn giữ quyền kiểm soát bằng cách hiểu câu trả lời, chứ không phải bằng cách học thuộc lý thuyết về chỉ mục.