Ok, trong thế giới PostgreSQL có vài loại index, mỗi loại sinh ra để làm một nhiệm vụ riêng biệt. Nó giống như chọn phương tiện di chuyển: đi dạo công viên thì đi xe đạp, còn muốn sang bên kia thành phố thì chắc chắn phải đi ô tô. Index cũng vậy, mỗi loại hợp với từng kiểu bài toán khác nhau.
Trong PostgreSQL, các loại index chính gồm có:
B-TREEindex: index đa năng cho hầu hết các trường hợp.HASHindex: tối ưu cho so sánh chính xác.GINindex: cực kỳ hợp để tìm kiếm trên array và JSONB.GiSTindex: dùng cho các kiểu dữ liệu phức tạp như địa lý.
Index sinh ra để tăng tốc tìm kiếm dòng dữ liệu. Có 4 kiểu tối ưu hóa khác nhau: mỗi loại tăng tốc cho một số thao tác nhất định và hợp với từng kiểu dữ liệu riêng.
Bạn không thể điều khiển index theo ý mình. Tất cả những gì bạn làm được là chọn loại index: hoặc không dùng, hoặc chọn một trong các loại kể trên. Giờ mình sẽ giải thích từng loại để bạn biết khi nào và cách dùng chúng.
Index B-TREE
B-TREE (viết tắt của "balanced tree") — là loại index phổ biến nhất, là nền tảng của PostgreSQL. Loại index này tạo ra một cấu trúc cây, trong đó dữ liệu được tổ chức để tăng tốc tìm kiếm, sắp xếp và lọc.
Hãy tưởng tượng một thư viện với các kệ sách, mỗi kệ chứa sách xếp theo thứ tự chữ cái. Nếu bạn tìm sách bắt đầu bằng "M", bạn không cần xem hết từng cuốn — chỉ cần bắt đầu từ giữa. Cây cân bằng cũng hoạt động kiểu như vậy.
Khi nào nên dùng?
Gần như lúc nào cũng được! B-TREE index đặc biệt hữu ích cho:
- Tìm kiếm theo khoảng:
WHERE price > 100. - Sắp xếp:
ORDER BY name ASC. - Tìm kiếm chính xác:
WHERE id = 42.
Lấy ví dụ tạo index:
-- Tạo index B-TREE cho cột price của bảng products:
CREATE INDEX idx_price ON products(price);
Khi bạn viết truy vấn kiểu WHERE price > 100, PostgreSQL sẽ dùng index này và không phải quét hết bảng.
Index HASH
HASH index dùng hash table để tìm kiếm nhanh. Điểm mạnh là so sánh chính xác giá trị. Nhưng HASH index có hạn chế: không hỗ trợ tìm kiếm theo khoảng hoặc sắp xếp.
Nó giống như một tủ hồ sơ, mỗi thẻ có số riêng. Bạn tìm thẻ số 42, thủ thư lấy ra ngay. Nhưng nếu bạn bảo: “cho tôi xem các thẻ từ 40 đến 50”, thì không được đâu.
HASH index chỉ hợp cho tìm kiếm chính xác:
WHERE email = 'user@example.com'.SELECT ... WHERE id = 123.
Nếu bạn cần tìm theo khoảng hoặc sắp xếp, thì HASH không hợp.
Ví dụ tạo index:
-- Tạo hash-index cho cột email của bảng users:
CREATE INDEX idx_email_hash ON users USING HASH (email);
Bây giờ PostgreSQL sẽ dùng index này cho truy vấn kiểu WHERE email = 'user@example.com'.
Lưu ý: HASH index chỉ hợp cho một số trường hợp đặc biệt và ít dùng hơn B-TREE.
Index GIN (Generalized Inverted Index)
GIN — là loại index chuyên dụng, cực kỳ bá đạo với array, JSONB và dữ liệu text. Hãy tưởng tượng bạn có một tủ với hàng ngàn ngăn kéo, mỗi ngăn có nhãn riêng. Ví dụ, ngăn "táo" chứa toàn táo, ngăn "chuối" chứa chuối. Muốn tìm táo hay chuối, bạn chỉ việc mở đúng ngăn, khỏi phải lục tung cả tủ.
GIN index dùng cho:
- Tìm kiếm trên array:
@>(chứa),<@(bị chứa). - Dữ liệu JSONB:
WHERE jsonb_data @> '{"key": "value"}'.
Ví dụ tạo index
-- Tạo GIN-index cho cột tags chứa array:
CREATE INDEX idx_tags_gin ON products USING GIN (tags);
Bây giờ PostgreSQL có thể tìm sản phẩm có tag kiểu "điện tử" và "được đề xuất" rất nhanh.
Index GiST (Generalized Search Tree)
GiST index — là công cụ mạnh để xử lý các kiểu dữ liệu phức tạp hơn, như tọa độ địa lý và khoảng giá trị. Nó xây dựng cây tối ưu cho tìm kiếm không gian và tìm kiếm theo khoảng.
Hãy tưởng tượng một bản đồ thành phố, mỗi điểm được đánh dấu theo tọa độ. Bạn có thể nhanh chóng tìm tất cả điểm trong bán kính 5km quanh vị trí hiện tại.
GiST hợp cho:
- Dữ liệu địa lý:
SELECT ... FROM locations WHERE ST_DWithin(geom, point, distance). - Tìm kiếm theo khoảng:
WHERE date_range && '[2023-01-01, 2023-12-31]'.
Ví dụ:
-- Tạo GiST-index cho cột location chứa dữ liệu địa lý:
CREATE INDEX idx_location_gist ON places USING GiST (location);
Bây giờ bạn có thể chạy các truy vấn địa lý phức tạp, ví dụ tìm điểm gần nhất.
Bảng so sánh các loại index
| Loại index | Phù hợp cho... | Ví dụ sử dụng | Ghi chú |
|---|---|---|---|
B-TREE |
Tìm kiếm theo khoảng, sắp xếp | price > 100, ORDER BY name ASC |
Index đa năng. |
HASH |
So sánh chính xác | email = 'user@example.com', id = 42 |
Không hỗ trợ tìm theo khoảng. |
GIN |
Array, JSONB | tags @> '{tech}', jsonb_data @> '{"key": "value"}' |
Nhanh hơn cho dữ liệu phức tạp. |
GiST |
Địa lý, khoảng, khoảng cách | ST_DWithin(geom, point, distance) |
Dùng cho dữ liệu địa lý. |
Giờ thì bạn đã biết các loại index cơ bản trong PostgreSQL và cách dùng chúng. Nhớ nhé: chọn index là một bước chiến lược, quyết định tốc độ truy vấn của bạn. Checkmate, mấy cái truy vấn chậm!
GO TO FULL VERSION