云数据库 PostgreSQL pgvector

这篇说说腾讯云pgvector插件,支持向量存储、相似度检索与HNSW/IVFFlat索引,适用于语义搜索、推荐等场景,并给出创建表、插入数据、距离查询及索引创建的完整示例。 向量类型与距离:支持L2、内积、余弦三种距离,通过操作符或函数计算。 索引选择:HNSW查询快但内存大,IVFFlat内存小适合大数据量。 使用注意:创建索引时操作符类需与距离类型一致,内积操作符返回负值。

相关产品
云数据库 PostgreSQL 产品页,含版本规格、价格与购买入口。

这里说明 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 产品文档

赞 (0)
上一篇 4天前
下一篇 4天前