本文为您介绍 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.236067977499792 | [2,3,4] | 3.74165738677394133 | [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 | -62 | -93 | -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.0027434893944259242 | 0.035098718645984681 | 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 | 0101 | 1.732050807568877299 | 1.732050807568877298 | 3.464101615137754497 | 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 参数平衡召回率与查询速度。