Vì B-tree sắp xếp theo thứ tự từ trái sang phải của giá trị.
- Với
LIKE 'abc%'database biết mọi kết quả nằm liền nhau trong khoảng['abc', 'abd')nên nhảy thẳng tới đó — đây là prefix search. - Với
'%abc%'thì phần đầu chuỗi không xác định, kết quả rải rác khắp cây, không có khoảng liên tục nào để nhảy vào → phải quét toàn bộ.
sql
SELECT * FROM users WHERE email LIKE 'nguyen%'; -- index range scan
SELECT * FROM users WHERE email LIKE '%gmail%'; -- full scanCách xử lý tìm chuỗi con:
- Trigram index (PostgreSQL, extension pg_trgm): cắt chuỗi thành các nhóm 3 ký tự và đánh index GIN lên đó, dùng được cho cả LIKE '%abc%' và ILIKE.
sql
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE INDEX idx_users_email_trgm ON users USING gin (email gin_trgm_ops);- Full-text search nếu thứ cần tìm là từ chứ không phải chuỗi con bất kỳ.
- Đảo chuỗi khi chỉ cần khớp đuôi: lưu thêm cột
reverse(domain)rồi tìm prefix trên cột đó. - Với nhu cầu tìm kiếm gõ-tới-đâu-gợi-ý-tới-đó ở quy mô lớn thì công cụ chuyên dụng (Elasticsearch, Meilisearch) hợp lý hơn.