跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

参考手册

pgvecto.rs 的 SQL Schema、索引选项、搜索选项与向量类型参考。

1 - 数据库 Schema

pgvecto.rs 提供的数据库数据类型、操作符、函数、类型转换与操作符类一览。

以下是 pgvecto.rs 提供的数据库对象定义(Schema)。

数据类型列表

名称 说明
vector 稠密向量,标量元素类型为 IEEE 754-2008 定义的 binary32(32 位浮点数)
vecf16 半精度向量,标量元素类型为 IEEE 754-2008 定义的 binary16(16 位浮点数)
veci8 整数向量,标量元素类型为 8-bit Integer(8 位有符号整数)
svector 稀疏向量,标量元素类型为 IEEE 754-2008 定义的 binary32(32 位浮点数)
bvector 二值向量,定长位串(bit string)
vector_index_stat 表示向量索引统计信息的复合类型

操作符列表

名称 左操作数类型 右操作数类型 返回类型 说明
+ vector vector vector 逐元素加法运算
+ vecf16 vecf16 vecf16 逐元素加法运算
+ veci8 veci8 veci8 逐元素加法运算
+ svector svector svector 逐元素加法运算
- vector vector vector 逐元素减法运算
- vecf16 vecf16 vecf16 逐元素减法运算
- veci8 veci8 veci8 逐元素减法运算
- svector svector svector 逐元素减法运算
& bvector bvector bvector 逐元素按位与(AND)
| bvector bvector bvector 逐元素按位或(OR)
^ bvector bvector bvector 逐元素按位异或(XOR)
= vector vector boolean 字典序比较
= vecf16 vecf16 boolean 字典序比较
= veci8 veci8 boolean 字典序比较
= svector svector boolean 字典序比较
= bvector bvector boolean 字典序比较
<> vector vector boolean 字典序比较
<> vecf16 vecf16 boolean 字典序比较
<> veci8 veci8 boolean 字典序比较
<> svector svector boolean 字典序比较
<> bvector bvector boolean 字典序比较
< vector vector boolean 字典序比较
< vecf16 vecf16 boolean 字典序比较
< veci8 veci8 boolean 字典序比较
< svector svector boolean 字典序比较
< bvector bvector boolean 字典序比较
> vector vector boolean 字典序比较
> vecf16 vecf16 boolean 字典序比较
> veci8 veci8 boolean 字典序比较
> svector svector boolean 字典序比较
> bvector bvector boolean 字典序比较
<= vector vector boolean 字典序比较
<= vecf16 vecf16 boolean 字典序比较
<= veci8 veci8 boolean 字典序比较
<= svector svector boolean 字典序比较
<= bvector bvector boolean 字典序比较
>= vector vector boolean 字典序比较
>= vecf16 vecf16 boolean 字典序比较
>= veci8 veci8 boolean 字典序比较
>= svector svector boolean 字典序比较
>= bvector bvector boolean 字典序比较
<-> vector vector real 平方欧氏距离
<-> vecf16 vecf16 real 平方欧氏距离
<-> veci8 veci8 real 平方欧氏距离
<-> svector svector real 平方欧氏距离
<-> bvector bvector real 平方欧氏距离
<#> vector vector real 负点积
<#> vecf16 vecf16 real 负点积
<#> veci8 veci8 real 负点积
<#> svector svector real 负点积
<#> bvector bvector real 负点积
<=> vector vector real 余弦距离
<=> vecf16 vecf16 real 余弦距离
<=> veci8 veci8 real 余弦距离
<=> svector svector real 余弦距离
<=> bvector bvector real 余弦距离
<~> bvector bvector real 杰卡德距离(Jaccard 距离)

函数列表

名称 参数类型 返回类型 说明
pgvectors_upgrade void 用于升级 pgvecto.rs 的管理函数。
to_svector dims integer, index integer[], value real[] svector 根据下标数组和值数组构造一个稀疏向量。
binarize vector vector bvector 将向量二值化:所有正数元素设为 1,其余元素设为 0。
text2vec_openai input text, model text vector 调用 OpenAI Embeddings API 的嵌入生成函数。
text2vec_openai_v3 input text vector 调用 OpenAI Embeddings API 的嵌入生成函数,默认模型设为 text-embedding-3-small。

类型转换列表

源类型 目标类型 是否隐式转换?
real[] vector yes
vector real[] yes
vector vecf16 no
vecf16 vector no
vector veci8 no
veci8 vector no
vector svector no
svector vector no
vector bvector no
bvector vector no

访问方法(Access Methods)列表

名称 类型 说明
vectors Index pgvecto.rs 向量索引方法

操作符族(Operator Families)列表

访问方法 操作符族 适用类型
vectors vector_cos_ops vector
vectors vector_dot_ops vector
vectors vector_l2_ops vector
vectors vecf16_cos_ops vecf16
vectors vecf16_dot_ops vecf16
vectors vecf16_l2_ops vecf16
vectors veci8_cos_ops veci8
vectors veci8_dot_ops veci8
vectors veci8_l2_ops veci8
vectors svector_cos_ops svector
vectors svector_dot_ops svector
vectors svector_l2_ops svector
vectors bvector_cos_ops bvector
vectors bvector_dot_ops bvector
vectors bvector_l2_ops bvector
vectors bvector_jaccard_ops bvector

操作符类(Operator Classes)列表

访问方法 输入类型 操作符类 是否默认? 说明
vectors vector vector_l2_ops no 平方欧氏距离
vectors vector vector_dot_ops no 负点积
vectors vector vector_cos_ops no 余弦距离
vectors vecf16 vecf16_l2_ops no 平方欧氏距离
vectors vecf16 vecf16_dot_ops no 负点积
vectors vecf16 vecf16_cos_ops no 余弦距离
vectors veci8 veci8_l2_ops no 平方欧氏距离
vectors veci8 veci8_dot_ops no 负点积
vectors veci8 veci8_cos_ops no 余弦距离
vectors svector svector_l2_ops no 平方欧氏距离
vectors svector svector_dot_ops no 负点积
vectors svector svector_cos_ops no 余弦距离
vectors bvector bvector_l2_ops no 平方欧氏距离
vectors bvector bvector_dot_ops no 负点积
vectors bvector bvector_cos_ops no 余弦距离
vectors bvector bvector_jaccard_ops no 杰卡德距离(Jaccard 距离)

视图列表

名称 说明
pg_vector_index_stat 提供向量索引统计信息的监控视图

2 - 索引选项

我们使用 TOML 语法来描述索引配置。以下是配置中各个键的含义说明。

我们使用 TOML 语法来表达索引的配置参数。以下是配置中各个顶层键(表)的含义:

键名 类型 说明
segment table 分段(Segment)相关选项。
optimizing table 后台优化相关选项。
indexing table 用于构建索引的算法配置。

segment 表选项

键名 类型 取值范围 默认值 说明
max_growing_segment_size integer [1, 4_000_000_000] 20_000 未建立索引的增长中分段的最大向量数量。
max_sealed_segment_size integer [1, 4_000_000_000] 1_000_000 已封存(建立索引)分段的最大向量数量。

optimizing 表选项

键名 类型 取值范围 默认值 说明
optimizing_threads integer [1, 65535] CPU 核心数的平方根 后台构建索引的最大线程数。
sealing_secs integer [1, 60] 60 见下方说明。
sealing_size integer [1, 4_000_000_000] 1 见下方说明。

如果一个写入分段(write segment)中的向量数大于 sealing_size,且在连续 sealing_secs 秒内没有接收到新数据,该写入分段将被转为已封存分段(sealed segment)以构建索引。

indexing 表选项

键名 类型 说明
flat table 若设置此表,索引将使用暴力搜索(flat)算法。
ivf table 若设置此表,索引将使用 IVF 算法。
hnsw table 若设置此表,索引将使用 HNSW 算法。

在上述三种索引算法中只能选择其一,默认值为 hnsw。

flat 表选项

键名 类型 说明
quantization table 要使用的量化算法配置。

ivf 表选项

键名 类型 取值范围 默认值 说明
nlist integer [1, 1_000_000] 1000 聚类单元(聚类中心)的数量。
nsample integer [1, 1_000_000] 65536 用于 K-Means 聚类训练的样本数量。
least_iterations integer [1, 1_000_000] 16 K-Means 聚类的最少迭代次数。
iterations integer [1, 1_000_000] 500 K-Means 聚类的最大迭代次数。
quantization table 要使用的量化算法配置。

hnsw 表选项

键名 类型 取值范围 默认值 说明
m integer [4, 128] 12 节点的最大连接度数。
ef_construction integer [10, 2000] 300 构建索引时的搜索范围。
quantization table 要使用的量化算法配置。

quantization 表选项

键名 类型 说明
trivial table 若设置此表,则不使用任何量化。
scalar table 若设置此表,则使用标量量化(Scalar Quantization)。
product table 若设置此表,则使用乘积量化(Product Quantization)。

在上述量化算法中只能选择其一,默认值为 trivial。

product 表选项

键名 类型 取值范围 默认值 说明
sample integer [1, 1_000_000] 65535 用于量化训练的样本数量。
ratio enum "x4", "x8", "x16", "x32", "x64" "x4" 量化的压缩比。

压缩比(ratio)表示存储向量时节省的内存比例。例如,对于标准 32 位浮点向量 vector,"x4" 表示内存占用降至原来的 14\frac{1}{4};如果您是在半精度向量 vecf16 上创建索引,则 "x4" 表示内存占用降至原来的 12\frac{1}{2}。

3 - 搜索选项

搜索选项通过 PostgreSQL GUC 参数进行配置。

搜索选项通过 PostgreSQL GUC 参数进行指定。

ivf 选项

以下选项仅对 IVF 算法生效。详情请参阅索引指南。

选项 类型 取值范围 默认值 说明
vectors.ivf_nprobe integer [1, 1_000_000] 10 扫描的列表数量。

hnsw 选项

以下选项仅对 HNSW 算法生效。详情请参阅索引指南。

选项 类型 取值范围 默认值 说明
vectors.hnsw_ef_search integer [1, 65535] 100 HNSW 的搜索范围。

其他选项

与搜索模式及规划器相关的查询选项:

选项 类型 取值范围 默认值 说明
vectors.search_mode enum "basic", "vbase" "vbase" 搜索模式,详情请参阅搜索指南。
vectors.pgvector_compatibility boolean off 启用或禁用 pgvector 兼容模式,详情请参阅 pgvector 兼容性。
vectors.enable_index boolean on 启用或禁用查询规划器对向量索引的使用。

4 - 向量类型

在前面的索引和搜索章节中,我们接触了 vector 类型。本节将探讨更多向量类型及其在向量搜索领域的应用。

在前面的索引和搜索章节中,我们已经接触了标准的 vector 类型。本节将探讨更多向量数据类型及其在向量搜索领域的应用:

低精度索引

since v0.3.0

为了提升在 vector 列上的查询速度并降低内存占用,可以考虑使用表达式索引,基于 vecf16、veci8 或 bvector 类型创建低精度索引,而非直接对 vector 类型创建全精度索引:

CREATE TABLE t (val vector(3));
INSERT INTO t (val) SELECT ARRAY[random(), random(), random()]::real[] FROM generate_series(1, 1000);

-- 在 vector 列上创建 bvector 二值向量索引
-- 注意:在构建索引时,Float32 向量会被截断为 0 或 1 的整数
CREATE INDEX lp_bin ON t USING vectors ((binarize(val)::bvector(3)) bvector_l2_ops);

-- 在 vector 列上创建 vecf16 半精度向量索引
CREATE INDEX lp_f16 ON t USING vectors ((val::vecf16(3)) vecf16_l2_ops);

-- 在 vector 列上创建 veci8 整数向量索引
-- 注意:在构建索引时,Float32 向量会被截断为 -128 到 127 之间的整数
CREATE INDEX lp_i8 ON t USING vectors ((val::veci8(3)) veci8_l2_ops);

缩短嵌入向量(Shortening Embedding)

since v0.3.0

部分嵌入模型(例如 OpenAI 的 text-embedding-3-small 和 text-embedding-3-large)支持缩短嵌入向量,即直接移除向量序列末尾的部分数值,而不会丢失嵌入向量的核心概念表达能力。

在某些场景下,可能需要在嵌入生成并入库之后再动态调整检索维度。pgvecto.rs 提供了通过数组切片语法直接使用缩短后的嵌入向量进行查询和建索引的方法:

CREATE TABLE t (val vector(3));
INSERT INTO t (val) SELECT ARRAY[random(), random(), random()]::real[] FROM generate_series(1, 1000);
CREATE INDEX ON t USING vectors (val vector_l2_ops);

-- 仅使用前两个维度计算距离
SELECT * from t ORDER BY (val[:2])::vector(2) <-> '[3, 2]'::vector;

自 v0.3.0 版本起,pgvecto.rs 中的所有向量数据类型均支持缩短嵌入向量切片操作。

类型转换

下图展示了不同向量数据类型之间的转换关系,由箭头连接的两个类型可以相互转换(Cast):

其中,ARRAY 是 PostgreSQL 的原生数组类型,其余均为 pgvecto.rs 定义的向量类型。

以下是向量类型转换的几个示例:

-- 合法:字符串 ⇒ vector
SELECT '{1,2,3}'::vector;

-- 合法:vector ⇒ ARRAY
SELECT '{1,2,3}'::vector::real[];

-- 合法:ARRAY ⇒ vector ⇒ bvector
SELECT ARRAY[1.0 ,0 ,0]::real[]::vector::bvector;

-- 报错:无法直接将类型 vecf16 转换为 veci8
SELECT '[3, 2]'::vecf16::veci8;

-- 合法:vecf16 ⇒ vector ⇒ veci8
SELECT '[3, 2]'::vecf16::vector::veci8;

4.1 - 半精度向量:`vecf16`

vecf16 以半精度浮点数格式存储,利用 16 位浮点数,与标准 vector 相比仅占用一半的内存和带宽。

vecf16 以半精度数值格式存储,充分利用了 16 位浮点数(FP16)的优势,与标准 32 位浮点数的 vector 相比,仅使用一半的内存和内存带宽。

以下是创建包含 vecf16 列的表并插入数据的示例:

CREATE TABLE items (
  id bigserial PRIMARY KEY,
  embedding vecf16(3) NOT NULL
);

INSERT INTO items (embedding) VALUES ('[0.1, 0.2, 0]'), ('[0, 0.1, 0.2]');

同样可以在 vecf16 类型上创建索引:

CREATE INDEX your_index_name ON items USING vectors (embedding vecf16_l2_ops);

SELECT * FROM items ORDER BY embedding <-> '[0.3,0.2,0.1]' LIMIT 1;

我们支持三种用于计算两个 vecf16 值之间距离的操作符:

  • <->(vecf16_l2_ops):平方欧氏距离,定义为 Σ(xi−yi)2\Sigma (x_i - y_i) ^ 2。
  • <#>(vecf16_dot_ops):负点积,定义为 −Σxiyi- \Sigma x_iy_i。
  • <=>(vecf16_cos_ops):余弦距离,定义为 1−ΣxiyiΣxi2Σyi21 - \frac{\Sigma x_iy_i}{\sqrt{\Sigma x_i^2 \Sigma y_i^2}}。

4.2 - 8 位整数向量:`veci8`

Int8 是用于表示有符号整数的数据类型,使用 8 位内存存储范围在 -128 到 127 之间的整数,显著降低向量存储的内存占用。
since v0.3.0

Int8 是一种用于表示有符号整数的数据类型,代表“8 位整数(integer 8-bit)”,使用 8 比特(1 字节)内存存储一个值,可表示范围为 -128 到 127 的整数。

由于向量中的每个元素仅需 8 比特(1 字节)内存,使用 veci8 可以大幅减少程序的整体内存占用。

以下是创建包含 veci8 列的表并插入数据的示例:

CREATE TABLE items (
  id bigserial PRIMARY KEY,
  embedding veci8(3) NOT NULL
);

INSERT INTO items (embedding) VALUES ('[1, 2, 0]'), ('[-1, 15, -2]');

同样可以在 veci8 类型上创建索引:

CREATE INDEX your_index_name ON items USING vectors (embedding veci8_l2_ops);

SELECT * FROM items ORDER BY embedding <-> '[0.3,0.2,0.1]' LIMIT 1;

我们支持三种用于计算两个 veci8 值之间距离的操作符:

  • <->(veci8_l2_ops):平方欧氏距离,定义为 Σ(xi−yi)2\Sigma (x_i - y_i) ^ 2。
  • <#>(veci8_dot_ops):负点积,定义为 −Σxiyi- \Sigma x_iy_i。
  • <=>(veci8_cos_ops):余弦距离,定义为 1−ΣxiyiΣxi2Σyi21 - \frac{\Sigma x_iy_i}{\sqrt{\Sigma x_i^2 \Sigma y_i^2}}。

4.3 - 稀疏向量:`svector`

与稠密向量不同,稀疏向量具有极高的维度,但仅包含少量非零值。
since v0.3.0

与稠密向量不同,稀疏向量(Sparse Vector)通常具有非常高的维度,但其中只包含极少数的非零值。

通常情况下,稀疏向量可以由以下方式生成:

  • 词共现矩阵(Word co-occurrence matrices)
  • 词频-逆文档频率(TF-IDF)向量或 SPLADE/BGE-M3 词法权重
  • 用户-物品交互矩阵(User-item interaction matrices)
  • 网络邻接矩阵(Network adjacency matrices)

在 pgvecto.rs 中,稀疏向量类型称为 svector。

以下是创建包含 svector 列的表并插入数据的示例:

CREATE TABLE items (
  id bigserial PRIMARY KEY,
  embedding svector(10) NOT NULL
);

INSERT INTO items (embedding) VALUES ('[0.1,0,0,0,0,0,0,0,0,0]'), ('[0,0,0,0,0,0,0,0,0,0.5]');

同样可以在 svector 类型上创建索引:

CREATE INDEX your_index_name ON items USING vectors (embedding svector_l2_ops);

SELECT * FROM items ORDER BY embedding <-> '[0.3,0,0,0,0,0,0,0,0,0]' LIMIT 1;

我们支持三种用于计算两个 svector 值之间距离的操作符:

  • <->(svector_l2_ops):平方欧氏距离,定义为 Σ(xi−yi)2\Sigma (x_i - y_i) ^ 2。
  • <#>(svector_dot_ops):负点积,定义为 −Σxiyi- \Sigma x_iy_i。
  • <=>(svector_cos_ops):余弦距离,定义为 1−ΣxiyiΣxi2Σyi21 - \frac{\Sigma x_iy_i}{\sqrt{\Sigma x_i^2 \Sigma y_i^2}}。

此外,还提供了 to_svector 函数用于构造 svector,它会在指定的下标位置设置对应的非零值:

F(index)={value[v]∃v∈N:position[v]=index0else F(index)=\left\{ \begin{array}{rcl} value[v] & & {\exists v \in \mathbb{N}: position[v] = index }\\ 0 & & {else}\\ \end{array} \right.
-- to_svector(dim: INTEGER, position: ARRAY, value: ARRAY) -> svector
SELECT to_svector(5, '{0, 4}', '{0.3, 0.5}');
-- [0.3, 0, 0, 0, 0.5]

4.4 - 二值向量:`bvector`

bvector 是 pgvecto.rs 中的二值向量类型,其每个分量仅取 0 或 1 两个可能值,并针对存储和距离计算进行了深度优化。
since v0.3.0

bvector 类型是 pgvecto.rs 中的二值向量(Binary Vector)类型。在二值向量中,每个分量只能取两个可能的值(通常为 0 和 1)。

以下是创建包含 bvector 列的表并插入数据的示例:

CREATE TABLE items (
  id bigserial PRIMARY KEY,
  embedding bvector(3) NOT NULL
);

INSERT INTO items (embedding) VALUES ('[1,0,1]'), ('[0,1,0]');

同样可以在 bvector 类型上创建索引:

CREATE INDEX your_index_name ON items USING vectors (embedding bvector_l2_ops);

SELECT * FROM items ORDER BY embedding <-> '[1,0,1]' LIMIT 5;

我们支持四种用于计算两个 bvector 值之间距离的操作符:

  • <->(bvector_l2_ops):平方欧氏距离,定义为 Σ(xi−yi)2\Sigma (x_i - y_i) ^ 2。对于二值向量,汉明距离(Hamming distance)与平方欧氏距离完全等价。
  • <#>(bvector_dot_ops):负点积,定义为 −Σxiyi- \Sigma x_iy_i。
  • <=>(bvector_cos_ops):余弦距离,定义为 1−ΣxiyiΣxi2Σyi21 - \frac{\Sigma x_iy_i}{\sqrt{\Sigma x_i^2 \Sigma y_i^2}}。
  • <~>(bvector_jaccard_ops):杰卡德距离(Jaccard distance),定义为 1−∣X∩Y∣∣X∪Y∣1 - \frac{|X\cap Y|}{|X\cup Y|}。

此外,还提供了 binarize 函数用于从 vector 构造 bvector,它会将向量元素二值化为 0 或 1:

F(element)={0element≤01element>0 F(element)=\left\{ \begin{array}{rcl} 0 & & {element \leq 0}\\ 1 & & {element > 0}\\ \end{array} \right.
-- binarize(source: vector) -> bvector
SELECT binarize('[-2, -1, 0, 1, 2]'::vector);
-- [0, 0, 0, 1, 1]

性能表现

bvector 类型针对存储和计算性能进行了深度优化。它采用按位紧缩(bit-packed)的表示方式存储二值向量,并且距离计算也专门针对位运算进行了加速优化。

以下是 bvector 类型的性能基准测试结果。测试使用 dbpedia-entities-openai3-text-embedding-3-large-3072-1M 数据集,运行在 Google Cloud 的 n2-standard-8(8 vCPU,32 GB 内存)虚拟机上。

我们向表中插入了 100 万条二值向量并运行 KNN 查询。为 100 万条 3072 维二值向量建立索引仅需约 600MB 内存,而使用标准 vector 类型对相同数量的向量建立索引则需要约 18GB 内存。

bvector

可以看到,单纯使用 bvector 的准确率虽不及 vector 类型,但如果结合采用自适应检索(Adaptive Retrieval),其准确率即可超过 95%。