Pg_vectorsearch:一种比 pgvector 的 IVFF 和 HNSW 更快的索引。
Pg_vectorsearch: An index that is faster than pgvector's IVFFlat and HNSW

原始链接: https://github.com/timescale/pg_vectorsearch

pg_vectorsearch 是一个 alpha 阶段的 PostgreSQL 扩展,用于高性能近似最近邻搜索,旨在测试而非生产。它提供 PRISM 索引,这是一种采用分层质心路由的 IVF 风格方法,使用带误差界限的 RaBitQ 量化、SIMD 距离计算,并通过 prism_rebalance 进行动态更新。它支持 1 亿+ 向量,并声称比 pgvector 的 IVFFlat/HNSW 查询和构建更快。PRISM 可为原生 vec32/vec16 列或现有 pgvector vector/halfvec 列建立索引,而无需更改查询。对 L2、内积或余弦使用操作符类;用 prism.nprobe 调优。搜索遍历质心树,扫描倒排列表,应用 RaBitQ 两阶段过滤,然后对全精度向量重新排序。要求:PostgreSQL 18+、GNU C11、Meson;可选 CBLAS。许可证:PostgreSQL。预发布版本升级可能需要删除并重建扩展和索引。

Timescale/TigerData 宣布了 **pg_vectorsearch**,这是一个开源 PostgreSQL 扩展,用于更快、更便宜的向量搜索。其新的 **PRISM 索引** 使用分区和压缩,而不是 HNSW 基于图的方法,声称查询更快、内存占用低得多,并且索引构建显著更快。在 1 亿个向量下,据报道 PRISM 在一台内存比 HNSW 少 4 倍的机器上实现了 **6 毫秒查询延迟**,索引构建速度提高 20 倍以上。 在 Hacker News 上,一位评论者询问它是否支持过滤,尤其是后置过滤,以及人们如何使用这些索引高效实现租户、用户或权限范围。作者回复并链接了配套博客文章,其中包含发布细节和基准测试声明。当时该帖子有 18 分和 2 条评论。
相关文章

原文

Build Coverage Coverity

A PostgreSQL extension for high-performance approximate nearest neighbor (ANN) search.

Status: alpha. Meant for testing, not production. Upgrading between prereleases may not be possible; plan to drop and recreate the extension and its indexes. See the changelog for known issues.

  • PRISM index (100M+ vectors) — IVF-style, with hierarchical routing
  • RaBitQ quantization with theoretical error bounds for two-stage search
  • SIMD-optimized distance computation (AVX2, AVX512, NEON)
  • Dynamic updates — inserts, updates and deletes, with posting-list splits via prism_rebalance (see Maintenance)
  • pgvector compatible — index existing vector and halfvec columns as-is (see Existing pgvector tables)

PRISM

PRISM (Partitioned Routing Index for Similarity Matching) is a PostgreSQL-native index access method that is conceptually similar to pgvector's IVFFlat, but it is built around state-of-the-art quantization, routing, and partitioning techniques. It is implemented in C for high performance and seamless integration with PostgreSQL.

The result: an index that is significantly faster than pgvector's IVFFlat and HNSW, for both querying and index building. In fact, compared to graph-based HNSW, PRISM is faster at equivalent recall on a 100-million-vector dataset, on an instance with a quarter of the memory.

To achieve this performance, PRISM uses a hierarchical centroid tree to partition vectors into clusters, and relies on the PostgreSQL buffer cache to keep that tree warm in memory. Vectors are RaBitQ-quantized and stored in posting lists with a page layout optimized for SIMD distance computation. The RaBitQ encoding carries error bounds that let a search rule out vectors that cannot possibly be nearest neighbors, so far fewer of them need reranking against the full-precision vectors stored in the table.

Query Flow:
1. Traverse centroid tree to find nearest clusters (buffer cache)
2. Scan posting lists for candidates (buffer cache, async I/O)
3. RaBitQ two-stage filtering: estimate → error bound → rerank
4. Full-precision reranking from heap
5. Return k nearest neighbors

For detailed architecture, see docs/architecture.md.

Install the extension first; see Building.

There are two ways to use a PRISM index. Pick the one that matches where your vectors live:

  • Native types. Starting fresh, or not using pgvector? Store vectors in pg_vectorsearch's own vec32 (float32) or vec16 (float16) columns. No other extension is needed.
  • Existing pgvector tables. Already have vector or halfvec columns? Install pg_vectorsearch next to pgvector and build a PRISM index on those columns as they are. Your table and queries stay unchanged.

Both paths build the same index and use the same operators (<->, <#>, <=>) and tuning knobs.

CREATE EXTENSION pg_vectorsearch;

-- PLAIN keeps the vector inline. EXTERNAL (the default) toasts a value
-- over ~2 kB, and rerank then pays an extra fetch the planner does not cost.
CREATE TABLE items (
    id serial PRIMARY KEY,
    embedding vec32(3) STORAGE PLAIN
);

-- Load first; the index is sized from the row count at CREATE INDEX.
-- 500 rows is enough for the planner to use the index.
INSERT INTO items (embedding)
SELECT ARRAY[i::real, (i % 7)::real, (i % 5)::real]::vec32
FROM generate_series(1, 1000) i;

-- For inner product or cosine, see Operator classes below.
CREATE INDEX ON items USING prism (embedding vec32_l2_ops);

-- 0 = auto (~0.95 recall). Raise for recall, lower for speed.
SET prism.nprobe = 40;

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

Use vec16 instead of vec32 to halve the space vectors take in the table, with the matching vec16_* operator classes.

If you already have a table with pgvector's vector or halfvec columns, you can build a PRISM index on it directly. Nothing about the table or your queries needs to change. vec32 and vec16 are binary-compatible with pgvector's vector and halfvec but have different names, so the two extensions can be installed side by side, even in the same schema.

-- The table you already have, included so the example runs on its own.
CREATE EXTENSION vector;

CREATE TABLE documents (
    id        bigserial PRIMARY KEY,
    body      text,
    embedding vector(384)
);
CREATE INDEX documents_embedding_hnsw
    ON documents USING hnsw (embedding vector_l2_ops);

-- Install pg_vectorsearch next to pgvector and build the index on the
-- existing column. The column is not rewritten or copied.
CREATE EXTENSION pg_vectorsearch;

CREATE INDEX documents_embedding_prism
    ON documents USING prism (embedding vec32_l2_ops);

-- Your queries keep working as before. PRISM is normally faster, so
-- the planner should prefer it over the HNSW index while both exist.
-- Verify with an EXPLAIN:
EXPLAIN (COSTS OFF)
SELECT id, body
FROM documents
ORDER BY embedding <-> (SELECT embedding FROM documents WHERE id = 42)
LIMIT 10;
--  Limit
--    InitPlan 1
--      ->  Index Scan using documents_pkey on documents documents_1
--            Index Cond: (id = 42)
--    ->  Index Scan using documents_embedding_prism on documents
--          Order By: (embedding <-> (InitPlan 1).col1)

-- Once you are happy with it, drop the HNSW index.
DROP INDEX documents_embedding_hnsw;

Use the PRISM operator class for the same distance metric as your HNSW index.

Pick the operator class for your distance metric and column type. L2 is the default.

Distance Operator vec32 / vector vec16 / halfvec
L2 <-> vec32_l2_ops vec16_l2_ops
Inner product <#> vec32_ip_ops vec16_ip_ops
Cosine <=> vec32_cosine_ops vec16_cosine_ops

When replacing an HNSW index, pgvector's vector_<metric>_ops maps to vec32_<metric>_ops and halfvec_<metric>_ops to vec16_<metric>_ops.

Defaults are tuned from large-scale benchmarks; most deployments only ever adjust prism.nprobe. See the tuning guide for every index parameter and GUC, their tradeoffs, and when changing them makes sense.

An insert appends to whichever posting list its vector routes to, so lists grow as rows arrive and never split on their own. Besides REINDEX, the prism_rebalance procedure splits oversized lists in place. See the maintenance guide for how it works and its current limitations.

Requirements:

  • PostgreSQL 18+ (with development headers)
  • GNU C11 compiler (GCC 11+ or Clang 14+)
  • Meson build system
  • Optional: CBLAS, for faster RaBitQ encoding. See Development.
# Release build
meson setup builddir --buildtype=release

# Build and install to PostgreSQL
meson install -C builddir

See the development guide for build options.

  • Tuning - Index parameters, GUCs, tradeoffs, defaults
  • Maintenance - Rebalancing and splitting posting lists
  • Architecture - High-level design and data structures
  • SIMD - SIMD build options and distance computation
  • Development - Build options, testing, CI scripts
  • RaBitQ - Binary quantization with theoretical error bounds (SIGMOD 2024)
  • SPFresh - LIRE protocol for incremental updates (SOSP 2023)
  • SPANN - Billion-scale ANN with boundary replication (NeurIPS 2021)
  • ScaNN for AlloyDB - Hierarchical clustering (Google)
  • pgvector - Vector type and operators for PostgreSQL
  • pgvectorscale - DiskANN-based vector index for PostgreSQL

The PostgreSQL License

联系我们 contact @ memedata.com