近似索引

更新时间:2025-04-22 07:14:31

默认情况下,pgvector执行精确的最近邻搜索,该搜索可提供完美的召回率。您可以通过添加索引使用近似的最近邻搜索,可提升检索速度但牺牲一部分召回率。与典型索引不同,增加近似索引后,查询结果可能存在差异。支持的近似索引类型包括:HNSWIVFFlat

HNSW

HNSW索引用于构建多层图结构。与IVFFlat相比,其查询性能更好(在速度-召回率权衡方面),但构建时间更长,且占用更多内存。此外,由于没有像IVFFlat那样的训练步骤,支持在表中没有任何数据的情况下创建索引。

创建HNSW索引

您可为您需要使用的距离创建相应索引。

欧几里得距离(L2)
内积距离
余弦距离
曼哈顿距离(L1)
汉明距离
Jaccard距离
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops);
说明

对于不同向量类型需要使用不同距离计算操作,例如,halfvec使用halfvec_l2_opssparsevec使用sparsevec_l2_ops,其他距离函数类似。

CREATE INDEX ON items USING hnsw (embedding vector_ip_ops);
CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops);
CREATE INDEX ON items USING hnsw (embedding vector_l1_ops);
CREATE INDEX ON items USING hnsw (embedding bit_hamming_ops);
CREATE INDEX ON items USING hnsw (embedding bit_jaccard_ops);

支持以下向量类型:

  • Vector:向量,最多支持2,000维。

  • Halfvec:半精度向量,最多支持4,000维。

  • Sparsevec:稀疏向量,最多支持1,000个非零元素。

  • Bit:位向量,最多支持64,000维。

索引创建选项

参数

描述

参数

描述

m

每层的最大连接数,默认为16。

ef_construction

构建图时动态候选列表的大小默认为64。值越高,召回率越佳,但将延长索引构建时间和插入速度。

示例

CREATE INDEX ON items USING hnsw (embedding vector_l2_ops) WITH (m = 16, ef_construction = 64);

查询选项

参数

描述

参数

描述

hnsw.ef_search

指定搜索时动态候选列表的大小,默认为40。值越高,召回率越佳,但查询速度越慢。

示例

  • 会话级设置。

    SET hnsw.ef_search = 100;
  • 事务级设置。在目标事务中使用SET LOCAL设置单个查询语句值。

    BEGIN;
    SET LOCAL hnsw.ef_search = 100;
    SELECT ...
    COMMIT;

IVFFlat

IVFFlat索引结合了倒排索引和向量搜索的优点,通过将向量划分为多个列表,然后搜索那些与查询向量最接近的子集列表。对比HNSW索引,其构建速度更快,占用的内存更少,但查询性能上较低(在速度-召回率权衡方面)。

要获得良好的召回率,需要注意以下三点:

  • 在表中已有数据的情况下创建索引。

  • 选择合适的列表数量。对于最多1M行的数据,建议从行数 / 1000开始,对于超过1M行的数据,建议从sqrt(行数)开始。

  • 查询时指定合理探针数,更高的探针数有助于提高召回率,但会降低查询速度,建议使用sqrt(列表数)

创建IVFFlat索引

您可为您需要使用的距离创建相应索引。

欧几里得距离(L2)
内积距离
余弦距离
汉明距离
CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100);
说明

对于不同向量类型需要使用不同距离计算操作,例如,halfvec使用halfvec_l2_opssparsevec使用sparsevec_l2_ops,其他距离函数类似。

CREATE INDEX ON items USING ivfflat (embedding vector_ip_ops) WITH (lists = 100);
CREATE INDEX ON items USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
CREATE INDEX ON items USING ivfflat (embedding bit_hamming_ops) WITH (lists = 100);

支持以下向量类型:

  • Vector:向量,最多支持2,000维。

  • Halfvec:半精度向量,最多支持4,000维。

  • Bit:位向量,最多支持64,000维。

查询选项

参数

描述

参数

描述

ivfflat.probes

指定探测次数,默认为1。值越高,召回率越佳,但查询速度越慢。可以将其设置为列表的数量以进行精确的最近邻搜索(此时规划器将不会使用索引)。

示例

事务级设置。在目标事务中使用SET LOCAL设置单个查询语句值。

BEGIN;
SET LOCAL ivfflat.probes = 10;
SELECT ...
COMMIT;

优化索引构建时间

索引创建速度与多个参数有关,如下所示:

参数

描述

参数

描述

maintenance_work_mem

定义集群在执行维护性操作(包括索引创建)时可用的内存大小。当图的所有数据可以容纳在maintenance_work_mem中时,将显著加快索引构建速度。不建议设置过高导致集群内存耗尽,请根据集群规格来调整该参数的值。

当图不再适合放入内存,系统将显示以下通知:

NOTICE:  hnsw 图在 100000 个元组后不再适合放入 maintenance_work_mem
DETAIL:  构建将需要显著更多的时间。
HINT:  增加 maintenance_work_mem 可以加速构建。
说明

仅针对HNSW索引构建优化。

max_parallel_maintenance_workers

定义并行工作线程数量,默认为2。可通过增加线程数加速索引构建。例如设置并行工作线程数量为8:

SET max_parallel_maintenance_workers = 7; -- 加上leader线程
说明

对于大量工作线程,您可以增加max_parallel_workers(默认为 8)。

此外,与其他索引类型类似,在加载初始数据后再创建索引的效率更高。HNSW索引创建选项对构建时间也有显著影响。

查询索引构建进度

可查看pg_stat_progress_create_index视图确认索引创建进度。

  • HNSW的阶段包括:

    1. initializing(初始化)

    2. loading tuples(加载元组)

  • IVFFlat的阶段包括:

    1. initializing(初始化)

    2. performing k-means(执行 k-means)

    3. assigning tuples(分配元组)

    4. loading tuples(加载元组)

--- HNSW
SELECT phase, round(100.0 * blocks_done / nullif(blocks_total, 0), 1) AS "%" FROM pg_stat_progress_create_index;

--- IVFFlat
SELECT phase, round(100.0 * tuples_done / nullif(tuples_total, 0), 1) AS "%" FROM pg_stat_progress_create_index;
说明

仅在loading tuples阶段更新%字段。

  • 本页导读
  • HNSW
  • 创建HNSW索引
  • 索引创建选项
  • 查询选项
  • IVFFlat
  • 创建IVFFlat索引
  • 查询选项
  • 优化索引构建时间
  • 查询索引构建进度