这里说明 pgvector 插件的简介及使用方法。
一、概述
pgvector 是向量检索插件,提供向量数据类型、相似度计算函数和向量索引,可用于语义搜索、推荐、图片检索等场景。
二、支持版本
| PostgreSQL 版本 | 内核版本 |
| PostgreSQL 12 | v12.22_r1.36及以上 |
| PostgreSQL 13 | v13.22_r1.31及以上 |
| PostgreSQL 14 | v14.19_r1.40及以上 |
| PostgreSQL 15 | v15.14_r1.25及以上 |
| PostgreSQL 16 | v16.10_r1.20及以上 |
| PostgreSQL 17 | v17.6_r1.14及以上 |
| PostgreSQL 18 | v18.1_r1.5及以上 |
注意:说明:
注意:你可在控制台实例详情页查看当前实例的内核版本,或执行 SHOW tencentdb_version; 查询。
三、插件简介
pgvector 支持 vector、halfvec、bit、sparsevec 等多种向量数据类型,提供基于 L2距离、内积、余弦距离的相似度检索能力,并提供 HNSW 与 IVFFlat 两种向量索引以加速近似最近邻(KNN)查询。
四、环境准备
在目标数据库中执行以下语句创建扩展:
postgres=> CREATE EXTENSION vector;CREATE EXTENSION
注意:说明:
注意:扩展名为 vector,创建后即可使用 vector 类型。
五、创建向量表与插入数据
vector(n) 表示 n 维向量。以下示例创建一张含3维向量的表并插入数据:
postgres=> CREATE TABLE items(id int, embedding vector(3));CREATE TABLEpostgres=> INSERT INTO items VALUES (1, '[1,2,3]'), (2, '[2,3,4]'), (3, '[10,11,12]');INSERT 0 3postgres=> SELECT * FROM items ORDER BY id; id | embedding—-+———— 1 | [1,2,3] 2 | [2,3,4] 3 | [10,11,12](3 rows)
六、距离操作符
pgvector 提供三种距离操作符:
| 操作符 | 含义 | 排序方向 |
| <-> | L2距离(欧氏距离) | 越小越相似 |
| <#> | 内积(取负值) | 越小越相似 |
| <=> | 余弦距离 | 越小越相似 |
按 L2距离查询最相似(最近)的向量:
postgres=> SELECT id, embedding <-> '[1,1,1]' AS l2_dist FROM items ORDER BY embedding <-> '[1,1,1]'; id | embedding | l2_dist—-+————+——————– 1 | [1,2,3] | 2.23606797749979 2 | [2,3,4] | 3.7416573867739413 3 | [10,11,12] | 17.378147196982766(3 rows)
按内积查询:
postgres=> SELECT id, embedding <#> '[1,1,1]' AS inner_prod FROM items ORDER BY embedding <#> '[1,1,1]' DESC; id | inner_prod—-+———— 1 | -6 2 | -9 3 | -33(3 rows)
注意:说明:
注意:<#> 返回的是负的内积值,便于与其他距离操作符保持“值越小越相似”的排序习惯。因此按内积相似度从高到低排序时,应使用 ORDER BY … DESC。
按余弦距离查询:
postgres=> SELECT id, embedding <=> '[1,1,1]' AS cosine_dist FROM items ORDER BY embedding <=> '[1,1,1]'; id | cosine_dist—-+———————- 3 | 0.002743489394425924 2 | 0.03509871864598468 1 | 0.07417990022744858(3 rows)
七、距离函数
也可使用距离函数进行计算。函数参数需显式指定 ::vector 类型:
postgres=> SELECT l2_distance('[1,2,3]'::vector, '[1,1,1]'::vector) AS l2, inner_product('[1,2,3]'::vector, '[1,1,1]'::vector) AS ip, cosine_distance('[1,2,3]'::vector, '[1,1,1]'::vector) AS cosine; l2 | ip | cosine——————+—-+——————— 2.23606797749979 | 6 | 0.07417990022744858(1 row)
注意:说明:
注意:距离函数返回真实值,inner_product 返回正的内积值,与操作符 <#> 的负值不同。
八、创建索引
为便于演示索引效果,先补充更多数据:
postgres=> INSERT INTO items SELECT i, ('['||i||','||(i+1)||','||(i+2)||']')::vector FROM generate_series(4, 200) AS i;INSERT 0 197
九、HNSW 索引
HNSW 索引查询速度快、召回率高,但内存占用较大:
postgres=> CREATE INDEX items_hnsw_idx ON items USING hnsw (embedding vector_l2_ops);CREATE INDEX
十、IVFFlat 索引
IVFFlat 索引内存占用小,适合数据量较大的场景,需通过 lists 指定聚类中心数:
postgres=> CREATE INDEX items_ivfflat_idx ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 10);CREATE INDEX
注意:说明:
注意:创建向量索引时,操作符类需与查询使用的距离类型一致,例如 vector_l2_ops 对应 <->,vector_ip_ops 对应 <#>,vector_cosine_ops 对应 <=>。
十一、近似最近邻查询
创建索引后,可按距离排序查询最相似的向量:
postgres=> SELECT id, embedding <-> '[100,101,102]' AS distance FROM items ORDER BY embedding <-> '[100,101,102]' LIMIT 5; id | distance—–+——————– 100 | 0 101 | 1.7320508075688772 99 | 1.7320508075688772 98 | 3.4641016151377544 97 | 5.196152422706632(5 rows)
十二、辅助函数
vector_dims 函数返回向量的维数:
postgres=> SELECT vector_dims('[1,2,3]'::vector) AS dims; dims—— 3(1 row)
十三、Q:内积查询的结果为什么是负数?
A:<#> 操作符返回负的内积值,这是为了保持“值越小越相似”的统一排序习惯。若需真实内积值,请使用 inner_product 函数。
十四、Q:IVFFlat 和 HNSW 索引如何选择?
A:HNSW 索引查询更快、召回率更高,但内存占用大、构建时间长;IVFFlat 索引内存占用小,适合数据量很大的场景,但需通过 lists 参数平衡召回率与查询速度。
十五、相关参考
pgvector 产品文档