1. 简介
pgvector 是一个开源的 PostgreSQL 扩展插件,用于在关系型数据库中实现高效的向量存储和相似性搜索。
源码地址:https://github.com/pgvector/pgvector
它的优势在于与 PostgreSQL 生态的继承,从而支持 ACID 事务、表连接等原生特性。
pgvector 为 PostgreSQL 新增 vector 数据类型,支持单精度(vector)、半精度(halfvec)、二进制(bit)、稀疏向量(sparsevec)。
pgvector 内置多种距离度量,包括 L2距离(欧式距离)、内积、余弦距离、L1距离(曼哈顿距离)、汉明距离、Jaccard 距离。
pgvector 的使用场景有:
- RAG(检索增强生成):为大语言模型(LLM)从知识库中快速检索与问题最相关的文档片段;
- 推荐系统:计算用户向量和内容向量之间的相似度,进行个性化推荐;
- 语义搜索:基于语义搜索相似关键字;
- 图片检索:通过向量化表示文字、图片,支持以图搜图或以文搜图;
- 相似性匹配:识别重复或相似的内容,如新闻去重、抄袭检测;
相比 Faiss 的优势:
- 基于 PostgreSQL 生态,无须加载全部向量到内存中;
- 支持向量的删除;
2. 安装
下载源码并安装。
git clone --branch v0.8.1 https://github.com/pgvector/pgvector.git
cd pgvector
make
make install
启用扩展插件。
CREATE EXTENSION IF NOT EXISTS vector;
查看插件是否安装成功。
SELECT * FROM pg_available_extention;
SELECT * FROM pg_extention;
3. 使用
创建一个表,其中 embedding 字段类型为 vector(3),表示 3 维向量。
CREATE TABLE items (
id bigserial PRIMARY KEY,
embedding vector(3)
);
插入数据:
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');
更新数据:
UPDATE items SET embedding = '[1,2,3]' WHERE id = 1;
删除数据:
DELETE FROM items WHERE id = 1;
查询数据,计算使用向量距离:
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
SELECT * FROM items WHERE embedding <-> '[3,1,2]' < 5;
向量距离计算函数:
- <->:L2距离
- <#>:内积
- <=>:余弦距离
- <+>:L1距离
- <~>:汉明距离
- <%>:Jaccard 距离
计算平均向量:
SELECT AVG(embedding) FROM items;
4. 索引
默认情况下,pgvector 精确计算最近邻搜索,提供最高的召回率。
可以添加索引来使用近似的最近邻搜索,牺牲一些召回率来换取查询速度,添加索引后查询结果会有所不同。
4.1 HNSW
HNSW 索引基于分层图结构,查询性能和召回率非常出色,但构建索引速度较慢,且占用内存更多。
可以在表中无数据时创建索引,不需要训练步骤。
创建 L2距离索引:
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops);
指定参数,m 表示每层的最大连接数,ef_construction 表示构建图的动态候选列表大小:
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops) WITH (m = 16, ef_construction = 64);
4.2 IVFFLAT
IVFFLAT 索引通过聚类机制将向量划分到多个列表中进行搜索,构建速度更快,内存占用更小,但查询性能与召回率的权衡通常不如 HNSW。
建议在表有数据后再创建索引。
创建 L2距离索引:
CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100);
参数 list 建议为表数据量 / 1000。