
pgvector là gì?
pgvector là extension mở rộng cho PostgreSQL cho phép lưu trữ,chỉ mục và tìm kiếm vector embedding ngay trong database quen thuộc. Thay vì vận hành một vector database riêng (Pinecone, Qdrant, Milvus), bạn có thể dùng PostgreSQL — database đã có sẵn trong stack — để làm cả relational data và vector search.
pgvector hỗ trợ các kiểu dữ liệu vector (vector, halfvec, bit, sparsevec), các hàm khoảng cách (L2 distance, inner product, cosine distance), và quan trọng nhất: index ANN (HNSW, IVFFlat) để tìm kiếm approximate nearest neighbor hiệu năng cao.

Tại sao chọn pgvector thay vì Vector Database riêng?
- Đơn giản hóa stack: Không cần service riêng, không cần sync data giữa PostgreSQL và vector DB
- ACID transactions: Vector data và relational data trong cùng transaction — consistency đảm bảo
- SQL quen thuộc: Dùng JOIN, WHERE, GROUP BY kết hợp vector search — power của SQL
- Chi phí thấp: Không trả phí managed vector DB, dùng PostgreSQL hiện có
- Mature ecosystem: Backup, replication, monitoring, pooling (PgBouncer) đã sẵn sàng
Cài đặt và cấu hình pgvector
Cài đặt
# Ubuntu/Debian
sudo apt install postgresql-16-pgvector
# Docker
docker run -d --name pgvector -e POSTGRES_PASSWORD=postgres pgvector/pgvector:pg16
# Từ source (cần PostgreSQL development headers)
git clone --branch v0.7.4 https://github.com/pgvector/pgvector.git
cd pgvector && make && sudo make install
Kích hoạt extension
-- Trong database cần dùng
CREATE EXTENSION vector;
-- Kiểm tra version
SELECT * FROM pg_available_extensions WHERE name = 'vector';
Lưu trữ và truy vấn vector
Tạo bảng với cột vector
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
content TEXT,
embedding VECTOR(1536), -- dimension tùy embedding model
metadata JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
Chèn dữ liệu
INSERT INTO documents (content, embedding, metadata)
VALUES (
'PostgreSQL pgvector cho vector search',
'[0.1, 0.2, ...]'::VECTOR, -- 1536 dimensions
'{"source": "blog", "category": "database"}'::JSONB
);
Tìm kiếm vector tương đồng (Cosine similarity)
-- Cosine similarity = 1 - cosine_distance
SELECT id, content, 1 - (embedding '[0.1, 0.2, ...]'::VECTOR) AS similarity
FROM documents
ORDER BY embedding '[0.1, 0.2, ...]'::VECTOR
LIMIT 5;
Toán tử = cosine distance, = L2 distance, = negative inner product (max inner product search).
Index ANN: HNSW vs IVFFlat
| Đặc điểm | HNSW | IVFFlat |
|---|---|---|
| Loại index | Graph-based (Hierarchical Navigable Small World) | Inverted file + flat quantization |
| Build time | Chậm hơn | Nhanh hơn |
| Search speed | Rất nhanh | Trung bình |
| Recall | Cao (99%+) | Thấp hơn, cần probes nhiều |
| Memory usage | Cao hơn | Thấp hơn |
| Phù hợp | Production, low latency, high recall | Dataset lớn, memory hạn chế |
Tạo HNSW index (khuyên dùng cho production)
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
m: Số kết nối mỗi node (default 16, tăng = recall cao hơn, memory cao hơn)ef_construction: Kích thước dynamic candidate list khi build (default 64)
Tạo IVFFlat index
CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
lists: Số clusters (thường = sqrt(N) vectors)- Cần
SET ivfflat.probes = 10;trước khi query để tăng recall
Hybrid Search: Vector + Full-text + Metadata
Sức mạnh thực sự của pgvector là kết hợp multiple search types trong một query:
-- Hybrid: Vector similarity + Full-text search + Metadata filter
SELECT
id,
content,
1 - (embedding $1) AS vec_sim,
ts_rank_cd(to_tsvector('vietnamese', content), plainto_tsquery('vietnamese', $2)) AS txt_rank
FROM documents
WHERE metadata->>'category' = 'tech'
AND embedding $1 < 0.3 -- cosine distance threshold
ORDER BY (0.7 * (1 - (embedding $1))) + (0.3 * ts_rank_cd(...)) DESC
LIMIT 10;
Hiệu năng và Benchmark
- 1M vectors, 768-dim: HNSW index ~2-3GB RAM, query p50 < 10ms, p99 < 50ms
- 10M vectors: Cần ~20-30GB RAM cho HNSW, IVFFlat nhẹ hơn nhưng recall thấp hơn
- Quantization: pgvector 0.7+ hỗ trợ
halfvec(16-bit) vàbit(1-bit) — giảm 2-32x storage/RAM

Best Practice Production
- Connection pooling: Bắt buộc dùng PgBouncer (transaction mode) — tránh connection exhaustion
- Partitioning: Partition bảng theo time (monthly) — dễ maintain, drop old data nhanh
- Partial index: Index chỉ vectors active (WHERE deleted_at IS NULL) — giảm index size
- Columnar storage: Kết hợp với
pg_columnarhoặchydracho analytical workloads - Monitoring: Theo dõi
pg_stat_statementscho vector queries,pg_buffercachecho index cache hit ratio
Khi nào KHÔNG nên dùng pgvector
- Dataset > 50M vectors, cần multi-node distributed → Milvus, Weaviate cluster
- Cần multi-modal search (text + image + audio) out-of-the-box → Weaviate
- Team không có PostgreSQL expertise, muốn zero-ops → Pinecone
- Cần real-time indexing (sub-second visibility sau INSERT) — pgvector HNSW cần REINDEX định kỳ
Kết luận
pgvector biến PostgreSQL thành vector database capable cho hầu hết use-case RAG, recommendation, semantic search. Với HNSW index, hybrid search SQL, ACID, và ecosystem mature — pgvector là lựa chọn pragmatic nhất cho team đã dùng PostgreSQL. Chỉ cần migrate sang vector DB chuyên biệt khi scale vượt giới hạn single-node PostgreSQL (~50M vectors).
Nguồn tham khảo: pgvector GitHub, PostgreSQL Documentation, Supabase pgvector Guide, Timescale pgvector Benchmark
