Pgvector của PostgreSQL: Tìm kiếm vector mạnh mẽ nhưng 'đuối sức' khi lọc dữ liệu? Cùng khám phá!
Lê Lân
0
Sử Dụng pgvector để Tìm Kiếm Vector trong PostgreSQL: Ưu Điểm, Hạn Chế và Giải Pháp Thực Tiễn
Mở Đầu
Trong bối cảnh ứng dụng trí tuệ nhân tạo (AI) phát triển nhanh chóng, việc lưu trữ và tìm kiếm các vector nhúng (embeddings) trở nên cực kỳ quan trọng. PostgreSQL, một trong những hệ quản trị cơ sở dữ liệu quan hệ phổ biến nhất, được nâng tầm với extension pgvector - cung cấp khả năng lưu trữ và truy vấn vector đa chiều cao cùng các phép toán tương tự và chỉ mục tìm kiếm tăng tốc.
Tuy nhiên, khi kết hợp tìm kiếm vector với các bộ lọc khác như metadata, ngày tháng, hay các thuộc tính khác, pgvector lại lộ ra những điểm hạn chế, đặc biệt là thiếu khả năng lọc trước (pre-filtering). Điều này dẫn đến việc phải thực hiện lọc sau (post-filtering), gây giảm hiệu suất tìm kiếm và thiếu chính xác trong kết quả trả về. Bài viết này sẽ phân tích chi tiết cách hoạt động của pgvector, trình bày kết quả thử nghiệm trên bộ dữ liệu giả lập, so sánh giữa tìm kiếm chính xác và gần đúng, và đề xuất các giải pháp khắc phục cũng như mô phỏng pre-filtering trong PostgreSQL.
Tổng quan về pgvector và Tìm kiếm Vector trong PostgreSQL
1. Giới thiệu về pgvector
pgvector là một extension mã nguồn mở cho PostgreSQL, thêm kiểu dữ liệu vector có số chiều lớn (ví dụ vector 512 chiều) vào cơ sở dữ liệu. Nó hỗ trợ:
Lưu trữ vector nhúng (embeddings) của dữ liệu như văn bản, hình ảnh, âm thanh.
Toán tử đo độ tương đồng như cosine similarity.
Index HNSW giúp tăng tốc tìm kiếm gần nhất (Nearest Neighbor Search).
Việc tích hợp trực tiếp vector embeddings vào cơ sở dữ liệu quan hệ cho phép kết hợp tìm kiếm vector với các điều kiện truy vấn truyền thống (SQL) trên metadata.
2. Tại sao cần tìm kiếm kết hợp với bộ lọc?
Thông thường, ngoài tìm kiếm vector, ta còn muốn giới hạn kết quả theo thuộc tính khác như màu sắc, ngày tháng, hay phân loại đặc thù. Ví dụ: tìm 15 điểm vector gần nhất trong nhóm ‘green’ (màu xanh lá) hoặc các tài liệu có ngày tạo gần đây cùng chứa nội dung tương tự.
3. Khó khăn trong việc kết hợp index vector và bộ lọc
PostgreSQL hỗ trợ nhiều kiểu index (B-tree, GIN, HNSW…) nhưng không thể kết hợp chúng hiệu quả trong một truy vấn.
pgvector chỉ hỗ trợ tìm kiếm gần đúng trên vector bằng index HNSW, không thể áp dụng bộ lọc trước ngay trong chỉ mục vector.
Kết quả là hệ thống phải tìm kiếm vector trước và sau đó mới lọc ra các kết quả thỏa mãn điều kiện bộ lọc (post-filtering), gây giảm độ chính xác và hiệu suất.
Thí Nghiệm Với Bộ Dữ Liệu Giả Lập Trên pgvector
1. Chuẩn bị môi trường
Khởi chạy container PostgreSQL với pgvector extension:
docker run --name pgv -d -e POSTGRES_PASSWORD=franck pgvector/pgvector:0.8.0-pg17
docker exec -it pgv psql -U postgres
create extension if not exists vector;
2. Tạo dữ liệu thử nghiệm
Hàm sinh vector ngẫu nhiên 512 chiều:
createfunction random_embedding(dimensions int) returns vector as
Lúc này độ recall và tốc độ tốt hơn, hạn chế mất mát kết quả do bộ lọc được áp dụng ngay trong chỉ mục.
Lưu ý: Phương pháp này chỉ áp dụng khi bộ lọc cố định và giá trị rõ ràng. Không linh hoạt cho bộ lọc phức tạp hoặc đa giá trị.
2. Điều chỉnh tham số chỉ mục HNSW
Tham số hnsw.ef_search quyết định số lượng candidate tìm kiếm, tăng giá trị này cải thiện recall nhưng làm chậm tìm kiếm.
set hnsw.ef_search =100;
3. Kích hoạt iterative scan
Khi kết quả sau post-filtering thấp hơn LIMIT, cho phép chạy lại index scan nhiều lần để đủ kết quả.
4. Phân vùng bảng (Partitioning)
Nếu dữ liệu được phân vùng theo trường lọc (vd: color), PostgreSQL áp dụng partition pruning giúp tăng tốc độ index scan và có thể cải thiện hiệu quả.
Tổng Kết và Đề Xuất
pgvector là công cụ mạnh giúp tích hợp tìm kiếm vector vào PostgreSQL, tiết kiệm việc quản lý thêm dịch vụ bên ngoài.
Tuy nhiên, hạn chế lớn là thiếu khả năng pre-filtering trên index vector, dẫn đến giảm recall và có thể ảnh hưởng đến độ chính xác tìm kiếm khi dùng bộ lọc metadata.
Partial index là giải pháp tạm thời hữu ích trong các trường hợp filter đơn giản, nhưng không thay thế được pre-filtering động.
Cần điều chỉnh tham số tìm kiếm và áp dụng iterative scan để cân bằng giữa tốc độ và độ chính xác.
PostgreSQL không thể kết hợp đồng thời các kiểu index (HNSW + B-tree) một cách trực tiếp, khác với MongoDB Atlas Vector Search có hỗ trợ pre-filtering động.
Khi triển khai ứng dụng nghiêm túc, cần cân nhắc cả lợi ích và hạn chế của pgvector, kiểm tra kỹ execution plan và kết quả trước khi áp dụng.
Lời khuyên: Với các hệ thống có yêu cầu tìm kiếm vector phức tạp kèm nhiều bộ lọc, xem xét dùng các nền tảng chuyên biệt như MongoDB Atlas Vector Search hoặc hệ thống vector search chuyên dụng sẽ mang lại hiệu quả lớn hơn.