Giải thích cho người mới · 10/2026

Chỉ mục
cơ sở dữ liệu

Hộp phiếu của thư viện giúp tìm sách nhanh hơn khoảng 79 lần, nhưng không phải lúc nào cũng vậy. Đo thật trên 100.000 cuốn sách.

Ví dụ đời thường Đo thật Đọc kế hoạch Bài tập có đáp án
SCAN books USING INDEX
Câu hỏi của bài này

Một câu hỏi, hai cách tìm

1Không có chỉ mục: đi dọc mọi kệ, mở từng cuốn. Với 100.000 cuốn mất khoảng 2,2 ms.
2Có chỉ mục: tra hộp phiếu rồi đi thẳng tới kệ. Khoảng 0,03 ms, nhanh hơn khoảng 79 lần.
3Nhưng không phải lúc nào cũng vậy. Số đo trên một máy. Cách mỗi hệ chọn kế hoạch phức tạp hơn nhiều, nên hình ảnh trong bài chỉ để dễ nhớ.
Hình dung trước

Đi dọc mọi kệ, hay tra hộp phiếu?

Quét toàn bảng

Đi dọc mọi kệ

Mở từng cuốn trong 100.000 cuốn xem có đúng tác giả không. Chậm, nhưng không cần chuẩn bị gì.

Chỉ mục

Tra hộp phiếu

Phiếu đã xếp sẵn theo tác giả, mỗi phiếu ghi sách nằm ở kệ nào. Nhanh, nhưng phải làm và giữ đúng mỗi khi nhập sách.

Hộp phiếu chỉ giúp khi câu hỏi khớp với cách nó được xếp.
Từ khó, nói dễ

Sáu từ sẽ gặp trong bài

Bảng

tên kỹ thuật: table

Cả kho sách xếp thành hàng. Mỗi hàng là một cuốn, các cột là tên sách, tác giả, năm.

Quét toàn bảng

tên kỹ thuật: full table scan

Đi dọc mọi kệ, mở từng cuốn để xem có phải thứ cần tìm không.

Chỉ mục

tên kỹ thuật: index

Hộp phiếu tra cứu xếp sẵn theo tác giả, mỗi phiếu ghi sách nằm ở đâu.

Kế hoạch truy vấn

tên kỹ thuật: query plan

Lời thủ thư nói trước: sẽ tra hộp phiếu hay sẽ đi dọc mọi kệ.

Độ chọn lọc

tên kỹ thuật: selectivity

Một điều kiện loại bỏ được bao nhiêu hàng. “Còn hàng” gần như không loại gì.

Chỉ mục nhiều cột

tên kỹ thuật: composite index

Hộp phiếu hai tầng: trước theo thể loại, trong mỗi thể loại theo năm.

Thí nghiệm thật · SQLite

Tìm một tác giả: nhanh hơn 79 lần

Quét toàn bảng2,204 ms
Có chỉ mục0,028 ms

100.000 cuốn, mỗi tác giả khoảng 50 cuốn, 200 lần đo lấy trung vị, SQLite 3.53.4 trong bộ nhớ.

79x

nhanh hơn (4 lần chạy cho 75 đến 82 lần)

Đọc kế hoạch

SCAN và SEARCH nói gì với bạn?

Quét cả bảng
SCAN books

Đi qua mọi hàng. Chậm dần khi bảng lớn lên.

Đi qua một phần
SEARCH books USING INDEX
idx_author (author=?)

Dùng chỉ mục. Dấu ngoặc cho biết điều kiện nào được dùng.

Gõ EXPLAIN QUERY PLAN trước câu truy vấn. Định dạng có thể đổi giữa các bản SQLite.
Chỗ chỉ mục không giúp

Dùng chỉ mục rồi mà không nhanh hơn

Quét toàn bảng39,9 ms
Có chỉ mục43,6 ms

WHERE in_stock = 1: 89.966 hàng kết quả, khoảng 90% bảng.

Truy vấn vẫn phải lấy gần cả bảng. Việc chính là đọc và chuyển 89.966 hàng, tra chỉ mục không bớt được phần đó. Đây là cách giải thích của tôi, chưa tách riêng từng bước.

Với in_stock = 0 (10% số hàng): 5,55 ms so với 5,03 ms, chỉ nhanh hơn khoảng 9%.

Thấy USING INDEX chưa có nghĩa là nhanh. Hỏi: điều kiện này loại bỏ bao nhiêu hàng?
Chỉ mục nhiều cột

Thứ tự cột quyết định chỉ mục có giúp

Chỉ mụcTruy vấn A: genre và yearTruy vấn B: chỉ year
(genre, year)0,437 ms · SEARCH2,067 ms · SCAN
(year, genre)0,561 ms · SEARCH0,694 ms · SEARCH

Không có chỉ mục nhiều cột thì truy vấn A quét 3,124 ms.

Hộp phiếu hai tầng, trước thể loại rồi tới năm. Hỏi “tech, từ 2020” thì đi thẳng tới ngăn tech. Hỏi “mọi sách năm 2015” thì năm 2015 rải rác ở mọi ngăn.

Nếu cả hai điều kiện là dấu bằng, cả hai thứ tự đều dùng đủ hai cột: 0,07 ms so với 1,6 ms khi quét.

Đặt lên đầu cột có mặt trong nhiều truy vấn thật nhất.
Có chỉ mục mà vẫn quét

Bốn cách hỏi cùng một tác giả

1lower(author) = 'author 1234'SCAN, 5,54 ms. Bọc cột trong hàm: chỉ mục xếp theo giá trị gốc.
2author LIKE '%1234'SCAN, 3,80 ms. Dấu % ở đầu: hộp phiếu xếp theo chữ đầu.
3author LIKE 'Author 1234%'SCAN, 2,85 ms. SQLite mặc định LIKE không phân biệt hoa thường, cần chỉ mục NOCASE.
4author GLOB 'Author 1234*'SEARCH, 0,029 ms. GLOB phân biệt hoa thường nên khớp chỉ mục mặc định.
Cái giá của chỉ mục

Ghi chậm hơn, tệp lớn hơn

0 chỉ mục6,4 ms
1 chỉ mục13,9 ms
3 chỉ mục31,8 ms

Thêm 20.000 hàng vào bảng 100.000 hàng, trung vị 7 lần, trong bộ nhớ.

Kích thước tệp
  • 0 chỉ mục: 4,98 MB
  • 1 chỉ mục: 7,48 MB
  • 3 chỉ mục: 12,23 MB

Chậm hơn 2,2 lần và 5 lần. Hãy dùng số này để thấy hướng, không để dự báo.

Ví dụ tính được

Tính thử: bảng lớn lên 50 lần

scan at 100,000 rows = 2.2 ms
5,000,000 / 100,000 = 50
2.2 ms * 50 = 110 ms

Minh họa: giả định thời gian quét tăng đều theo số hàng. Đây là phép nhân, không phải số đo.

Một lượt tìm tác giả trên 5 triệu sách có thể mất khoảng 110 ms thay vì 2,2 ms.

Tra chỉ mục đi qua vài tầng của một cây tìm kiếm (theo tài liệu PostgreSQL), nên tăng rất chậm theo số hàng.

Minh họa, không có thật

Minh họa: ổn lúc đầu, chậm về sau

Lúc đầu
10:00 · DevThêm màn tìm sách theo tác giả.
10:20 · AgentXong. WHERE author = ?, thử trên 1.000 sách, dưới 1 ms.
Ba tháng sau
09:30 · Người dùngTìm theo tác giả chậm quá, kho đã có 5 triệu sách.
09:45 · DevEXPLAIN cho SCAN books. Thêm chỉ mục author rồi đo lại.
Khi duyệt truy vấn mới, hỏi kế hoạch và số hàng dự kiến.
Chỗ hay sai

Năm chỗ chỉ mục hay đi sai

1Thêm chỉ mục cho mọi cột “cho chắc”Ghi chậm 5 lần với ba chỉ mục. Bỏ chỉ mục không xuất hiện trong kế hoạch thật.
2Chỉ mục trên cột ít giá trịTruy vấn vẫn lấy phần lớn bảng. Hỏi điều kiện loại bỏ bao nhiêu hàng.
3Sai thứ tự cộtTruy vấn chỉ lọc cột sau bị quét. Đặt cột có mặt nhiều nhất lên đầu.
4Bọc cột trong hàm, % ở đầu LIKEChỉ mục bị bỏ qua. Viết điều kiện trực tiếp trên cột, đọc kế hoạch.
5Không bao giờ xem kế hoạchBảng nhỏ thì cái gì cũng nhanh. Đưa việc đọc kế hoạch vào danh sách kiểm.
Bài tập có đáp án

Ba bài tập: đoán trước rồi chạy

1year = 2015 AND genre = 'tech': thứ tự nào dùng đủ hai cột?Đáp án: cả hai, khoảng 0,07 ms so với 1,6 ms khi quét.
2Chỉ mục in_stock: vì sao = 0 và = 1 đều ít lợi?Đáp án: lấy nhiều hàng. 5,55 so với 5,03 ms và 39,2 so với 41,7 ms.
3LIKE 'Author 1234%' vẫn SCAN: sửa bằng hai cách?Đáp án: dùng GLOB, hoặc tạo chỉ mục author COLLATE NOCASE (đều 0,029 ms).
Danh sách kiểm

Tám câu hỏi trước khi duyệt truy vấn

1Bảng sẽ có bao nhiêu hàng sau một năm?
2Tôi đã đọc kế hoạch: SCAN hay SEARCH?
3Điều kiện loại bỏ khoảng bao nhiêu % hàng?
4Có bọc cột trong hàm hoặc % ở đầu LIKE?
5Cột đứng đầu có mặt trong truy vấn thật?
6Chi phí ghi của chỉ mục mới chấp nhận được?
7Có chỉ mục cũ nào không còn được dùng?
8AI đã dán kế hoạch và số hàng giả định?
Nhìn cân bằng

Nhìn cân bằng: chắc và chưa chắc

Khá chắc
  • Chỉ mục có thể nhanh hơn hàng chục lần ở 100.000 hàng
  • Độ chọn lọc, thứ tự cột và cách viết điều kiện quyết định
  • Chỉ mục làm ghi chậm hơn và tốn chỗ
Cần thận trọng
  • Một máy, trong bộ nhớ, dữ liệu ngẫu nhiên đều
  • SQLite không phải PostgreSQL hay MySQL
  • Số 79 lần là của thí nghiệm này, không phải lời hứa
Kết luận

Đọc kế hoạch, hỏi độ chọn lọc, đo lại sau khi thêm.

Chỉ mục là hộp phiếu: rất nhanh khi câu hỏi khớp cách xếp, vô dụng khi không khớp, và luôn tốn công giữ. Với truy vấn do AI viết, hãy đòi chính kế hoạch đó làm bằng chứng.