
Index trong database là gì?
Database index giống như mục lục của sách: giúp database engine tìm dòng nhanh mà không cần quét toàn bộ table. Tuy nhiên, mỗi loại index phù hợp với kiểu truy vấn và pattern dữ liệu khác nhau.
Chọn đúng loại index có thể giảm query time từ vài giây xuống vài mili-giây, đồng thời giảm CPU và I/O đáng kể. Ngược lại, index sai có thể làm chậm writes và lãng phí RAM.

B-tree: mặc định phổ biến
B-tree (hay B+ tree trong PostgreSQL/MySQL) là loại index mặc định cho hầu hết cột dùng cho =, <, >, BETWEEN, ORDER BY. Cây cân bằng, chiều cao thấp, phù hợp dữ liệu sorted.
- Use case: primary key, email, timestamp, cột equality/range.
- Ưu điểm: ổn định, hỗ trợ range query tốt, cache-friendly.
- Nhược điểm: không tối ưu cho equality trên column có rất nhiều duplicate values.
Hash index: lookup O(1)
Hash index dùng hàm băm để ánh xạ giá trị sang bucket. Trong PostgreSQL, hash index chỉ hỗ trợ = tuyệt đối, không hỗ trợ range hay ORDER BY.
- Use case: session table lookup, cache key, equality nhiều lần trên cột có cardinality cao.
- Ưu điểm: tốc độ equality nhanh nhất.
- Nhược điểm: không hỗ trợ range, partition không tự cân bằng khi data growth không đều.

GIN: Generalized Inverted Index
GIN được thiết kế cho dữ liệu composite: JSONB, full-text search, array, tsvector. Một entry trong index chứa tất cả các token/con value của một dòng, tối ưu cho truy vấn kiểm tra “có chứa hay không”.
- Use case:
JSONB @>,array @>,to_tsvector, tìm kiếm trong text dài. - Ưu điểm: duy nhất phù hợp cho JSONB/array, hiệu năng tuyệt vời với Gin.
- Nhược điểm: insert/update chậm hơn B-tree do phải cập nhật nhiều entry.

BRIN: Block Range Index
BRIN lưu trữ thông tin min/max trên range block vật lý thay vì lưu từng entry như B-tree. Kích thước index cực nhỏ, phù hợp với dữ liệu có thứ tự tự nhiên và thời gian lớn.
- Use case: log IoT, sensor data, event timestamp, time-series với insert theo thứ tự.
- Ưu điểm: nhẹ, nhanh insert, storage cực thấp.
- Nhược điểm: hiệu quả giảm khi data có thứ tự lộn xộn, range selectivity thấp.
Quy tắc chọn index thực tế
Thứ tự ưu tiên: equality + range phổ biến → B-tree. JSONB/array/search → GIN. Time-series lớn insert theo thứ tự → BRIN. Hash chỉ dùng khi chắc chắn chỉ cần = và muốn tốc độ cực nhanh.
Luôn đo bằng EXPLAIN ANALYZE trước và sau khi tạo index. Một index có thể phá hỏng write performance nếu bảng có INSERT/UPDATE cao. Partitioning + BRIN thường là giải pháp cân bằng tốt nhất cho time-series.
Nguồn: PostgreSQL Documentation – Index Types, Use The Index, Luke!
