AI 与向量

IVFFlat 索引


IVFFlat 是一种用于近似最近邻搜索的向量索引类型。它是常用的索引类型,在查询高维向量(如表示嵌入的向量)时可提升性能。

选择索引

目前 pgvector 支持两种索引类型:

通常我们推荐使用 HNSW,因为它的性能表现对数据变化的鲁棒性。如果您有特殊用例需要使用 IVFFlat,请继续阅读。

使用方法

创建 IVFFlat 索引的方式取决于您使用的距离运算符。pgvector 包含 3 种距离运算符:

运算符描述运算符类
<->欧几里得距离vector_l2_ops
<#>负内积vector_ip_ops
<=>余弦距离vector_cosine_ops

根据查询中使用的运算符,使用以下 SQL 命令创建相应的 IVFFlat 索引。

欧几里得 L2 距离 (vector_l2_ops)

1
create index on items using ivfflat (column_name vector_l2_ops) with (lists = 100);

内积 (vector_ip_ops)

1
create index on items using ivfflat (column_name vector_ip_ops) with (lists = 100);

余弦距离 (vector_cosine_ops)

1
create index on items using ivfflat (column_name vector_cosine_ops) with (lists = 100);

当前最多支持为2,000维的向量创建索引。

IVFFlat 工作原理

IVF 代表"倒排文件索引"(inverted file indexes)。它通过聚类向量来缩小相似性搜索范围。不同于将向量与所有其他向量进行比较,IVF 只将向量与同一单元格簇(或附近簇,取决于配置)内的向量进行比较。

倒排列表(单元格簇)

创建索引时,您需要选择倒排列表(单元格簇)的数量。增加此数量可以加速查询,但会降低召回率。

例如,在使用了余弦运算符的列上创建包含100个列表的索引:

1
create index on items using ivfflat (column_name vector_cosine_ops) with (lists = 100);

有关不同运算符的更多信息,请参阅距离运算符

对于每个查询,您可以设置探测数量(默认为1)。探测数量对应于要搜索匹配项的附近单元格数量。增加此值可以提高召回率,但会降低速度。

要为当前会话设置探测数量,请运行:

1
set ivfflat.probes = 10;

要仅为当前事务设置探测数量,请运行:

1
2
3
4
begin;set local ivfflat.probes = 10;select ...commit;

如果探测数量与列表数量相同,则将执行精确最近邻搜索,且规划器不会使用索引。

近似最近邻

关于 IVF 索引的一个重要注意事项是:最近邻搜索是近似搜索,因为高维数据的精确搜索无法被高效索引。这意味着在添加索引后,相似性结果会(略微)发生变化(这是用召回率换取速度的权衡)。

何时应该创建 IVFFlat 索引?

pgvector 建议仅在表中已有足够数据后才构建 IVFFlat 索引,这样 IVFFlat 内部单元聚类才能基于您数据的实际分布。每当数据分布发生显著变化时,应考虑重建索引。

相关资源

pgvectorGitHub 页面 上阅读更多关于索引的信息。