Overzicht van pg_vectorsearch
pg_vectorsearch is een PostgreSQL-extensie die is ontwikkeld voor hoogwaardige approximate nearest neighbor (ANN) zoekopdrachten. De extensie introduceert de PRISM-index (Partitioned Routing Index for Similarity Matching), die gebruikmaakt van hiërarchische routing en RaBitQ-kwantisering. Hierdoor is de index aanzienlijk sneller en geheugenefficiënter dan de IVFFlat en HNSW indexen van pgvector, vooral bij zeer grote datasets (100M+ vectoren).
Belangrijkste kenmerken:
- Technische optimalisaties: Maakt gebruik van SIMD-geoptimaliseerde afstandsberekeningen (AVX2, AVX512, NEON) en een hiërarchische centroid-boom.
- Compatibiliteit: De extensie is compatibel met bestaande
pgvector-tabellen, waardoor gebruikers een PRISM-index kunnen bouwen op bestaande vector- en halfvec-kolommen zonder de data te herschrijven.
- Native types: Biedt eigen types zoals
vec32 en vec16 voor optimale opslag.
- Ondersteuning: Ondersteunt L2, Inner Product en Cosine distance.
Beheer en Installatie:
De extensie bevindt zich momenteel in de Alpha-fase. Voor onderhoud biedt het de prism_rebalance procedure om te grote posting-lijsten in place te splitsen. Installatie vereist PostgreSQL 18+, een GNU C11 compiler en het Meson build-systeem.
pg_vectorsearch: Hoogwaardige vectorsearch voor PostgreSQL
Status: Alpha. Bedoeld voor testen, niet voor productie. Upgraden tussen pre-releases is mogelijk niet mogelijk; houd er rekening mee dat de extensie en de indexen verwijderd en opnieuw aangemaakt moeten worden. Raadpleeg het changelog voor bekende problemen.
Belangrijkste kenmerken
- PRISM-index (100M+ vectoren): IVF-stijl, met hiërarchische routing.
- RaBitQ-kwantisering: Met theoretische foutmarges voor tweestapszoekopdrachten.
- SIMD-geoptimaliseerde afstandsberekening: Ondersteuning voor AVX2, AVX512 en NEON.
- Dynamische updates: Ondersteuning voor inserts, updates en deletes, met posting-list splits via
prism_rebalance (zie Onderhoud).
- pgvector-compatibel: Bestaande
vector- en halfvec-kolommen kunnen direct worden geïndexeerd (zie Bestaande pgvector-tabellen).
De PRISM-index
PRISM (Partitioned Routing Index for Similarity Matching) is een PostgreSQL-native index-toegangsmethode. Conceptueel is het vergelijkbaar met de IVFFlat van pgvector, maar het is gebouwd rond state-of-the-art kwantisering, routing en partitioneringstechnieken. De implementatie is in C voor hoge prestaties en naadloze integratie met PostgreSQL.
Het resultaat is een index die significant sneller is dan de IVFFlat en HNSW van pgvector, zowel bij het uitvoeren van queries als bij het bouwen van de index. In vergelijking met de grafiekgebaseerde HNSW is PRISM sneller bij een gelijkwaardige recall op een dataset van 100 miljoen vectoren, terwijl er slechts een kwart van het geheugen nodig is op een instance.
Om deze prestaties te bereiken, gebruikt PRISM een hiërarchische centroid-boom om vectoren in clusters te verdelen, waarbij vertrouwd wordt op de PostgreSQL buffer cache om die boom in het geheugen te houden. Vectoren worden RaBitQ-gekwantiseerd en opgeslagen in posting lists met een paginalay-out die is geoptimaliseerd voor SIMD-afstandsberekeningen. De RaBitQ-codering bevat foutmarges waardoor een zoekopdracht vectoren kan uitsluiten die onmogelijk de dichtstbijzijnde buren kunnen zijn. Hierdoor hoeven er aanzienlijk minder vectoren opnieuw gerangschikt te worden tegen de volledige precisie-vectoren die in de tabel zijn opgeslagen.
Query-flow:
- Doorloop de centroid-boom om de dichtstbijzijnde clusters te vinden (buffer cache).
- Scan de posting lists voor kandidaten (buffer cache, async I/O).
- RaBitQ tweestapsfiltering: schatting → foutmarge → herrangschikking.
- Volledige precisie-herrangschikking vanuit de heap.
- Retourneer de $k$ dichtstbijzijnde buren.
Voor gedetailleerde architectuur, zie docs/architecture.md.
Gebruik
Installeer eerst de extensie (zie Installatie). Er zijn twee manieren om een PRISM-index te gebruiken, afhankelijk van waar uw vectoren zijn opgeslagen:
- Native types: Wanneer u opnieuw begint of geen gebruik maakt van
pgvector. Sla vectoren op in de eigen vec32 (float32) of vec16 (float16) kolommen van pg_vectorsearch. Er is geen andere extensie nodig.
- Bestaande pgvector-tabellen: Heeft u al
vector- of halfvec-kolommen? Installeer pg_vectorsearch naast pgvector en bouw een PRISM-index op deze kolommen zoals ze zijn. Uw tabel en queries blijven ongewijzigd.
Beide methoden bouwen dezelfde index en maken gebruik van dezelfde operatoren (<->, <#>, <=>) en instellingen.
Native types
CREATE EXTENSION pg_vectorsearch;
-- PLAIN houdt de vector inline. EXTERNAL (standaard) gebruikt TOAST voor
-- waarden boven ~2 kB, wat een extra fetch veroorzaakt die de planner niet meerekent.
CREATE TABLE items (
id serial PRIMARY KEY,
embedding vec32(3) STORAGE PLAIN
);
-- Laad eerst de data; de index wordt gebaseerd op het aantal rijen bij CREATE INDEX.
-- 500 rijen zijn voldoende om de planner de index te laten gebruiken.
INSERT INTO items (embedding)
SELECT ARRAY[i::real, (i % 7)::real, (i % 5)::real]::vec32
FROM generate_series(1, 1000) i;
-- Voor inner product of cosine, zie Operator-klassen hieronder.
CREATE INDEX ON items USING prism (embedding vec32_l2_ops);
-- 0 = auto (~0.95 recall). Verhoog voor recall, verlaag voor snelheid.
SET prism.nprobe = 40;
SELECT * FROM items
ORDER BY embedding <-> '[3,1,2]'
LIMIT 5;
Gebruik vec16 in plaats van vec32 om de ruimte die vectoren in de tabel innemen te halveren, in combinatie met de bijbehorende vec16_* operator-klassen.
Bestaande pgvector-tabellen
Als u al een tabel heeft met vector- of halfvec-kolommen van pgvector, kunt u hier direct een PRISM-index op bouwen. Niets aan de tabel of uw queries hoeft te veranderen.
vec32 en vec16 zijn binair compatibel met de vector en halfvec van pgvector, maar hebben andere namen. Hierdoor kunnen beide extensies naast elkaar worden geïnstalleerd, zelfs in hetzelfde schema.
-- De tabel die u al heeft (opgenomen zodat het voorbeeld zelfstandig werkt).
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);
-- Installeer pg_vectorsearch naast pgvector en bouw de index op de bestaande kolom.
-- De kolom wordt niet herschreven of gekopieerd.
CREATE EXTENSION pg_vectorsearch;
CREATE INDEX documents_embedding_prism
ON documents USING prism (embedding vec32_l2_ops);
-- Uw queries blijven werken zoals voorheen. PRISM is normaal gesproken sneller,
-- dus de planner zou de voorkeur moeten geven aan PRISM boven de HNSW-index.
-- Verifieer dit met EXPLAIN:
EXPLAIN (COSTS OFF)
SELECT id, body
FROM documents
ORDER BY embedding <-> (SELECT embedding FROM documents WHERE id = 42)
LIMIT 10;
-- Resultaat:
-- 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)
-- Zodra u tevreden bent, kunt u de HNSW-index verwijderen.
DROP INDEX documents_embedding_hnsw;
Gebruik de PRISM operator-klasse voor dezelfde afstandsmetriek als uw HNSW-index.
Operator-klassen
Kies de operator-klasse op basis van de afstandsmetriek en het kolomtype. L2 is de standaard.
| Afstand | Operator | vec32 / vector | vec16 / halfvec |
| L2 | <-> | vec32l2ops | vec16l2ops |
| Inner product | <#> | vec32ipops | vec16ipops |
| Cosine | <=> | vec32cosineops | vec16cosineops |
Bij het vervangen van een HNSW-index komt vector<metriek>ops van pgvector overeen met vec32<metriek>ops en halfvec<metriek>ops met vec16<metriek>ops.
Tuning
De standaardinstellingen zijn afgestemd op basis van grootschalige benchmarks; de meeste implementaties passen alleen prism.nprobe aan. Zie de tuning-gids voor elke indexparameter en GUC, hun trade-offs en wanneer het zinvol is om ze te wijzigen.
Onderhoud
Een insert voegt gegevens toe aan de posting list waar de vector naartoe wordt gerouteerd. Hierdoor groeien lijsten naarmate er rijen worden toegevoegd, maar splitsen ze nooit automatisch. Naast REINDEX splitst de procedure prism_rebalance te grote lijsten in place. Zie de onderhoudsgids voor de werking en huidige beperkingen.
Installatie
Vereisten:
- PostgreSQL 18+ (met development headers)
- GNU C11 compiler (GCC 11+ of Clang 14+)
- Meson build system
- Optioneel: CBLAS, voor snellere RaBitQ-codering.
Build stappen:
# Release build
meson setup builddir --buildtype=release
# Build en installatie naar PostgreSQL
meson install -C builddir
Zie de development-gids voor aanvullende build-opties.
Documentatie
- Tuning - Indexparameters, GUC's, trade-offs, standaarden.
- Onderhoud - Rebalancing en het splitsen van posting-lijsten.
- Architectuur - High-level design en datastructuren.
- SIMD - SIMD build-opties en afstandsberekening.
- Development - Build-opties, testen, CI-scripts.
Referenties
Onderzoek
- 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)
Gerelateerde Projecten
- pgvector - Vector type en operatoren voor PostgreSQL.
- pgvectorscale - DiskANN-gebaseerde vector index voor PostgreSQL.
Licentie
The PostgreSQL License
pg_vectorsearch: Hoogwaardige vectorsearch voor PostgreSQL
Status: Alpha. Bedoeld voor testen, niet voor productie. Upgraden tussen pre-releases is mogelijk niet mogelijk; houd er rekening mee dat de extensie en de indexen verwijderd en opnieuw aangemaakt moeten worden. Raadpleeg het changelog voor bekende problemen.
Belangrijkste kenmerken
- PRISM-index (100M+ vectoren): IVF-stijl, met hiërarchische routing.
- RaBitQ-kwantisering: Met theoretische foutmarges voor tweestapszoekopdrachten.
- SIMD-geoptimaliseerde afstandsberekening: Ondersteuning voor AVX2, AVX512 en NEON.
- Dynamische updates: Ondersteuning voor inserts, updates en deletes, met posting-list splits via
prism_rebalance (zie Onderhoud).
- pgvector-compatibel: Bestaande
vector- en halfvec-kolommen kunnen direct worden geïndexeerd (zie Bestaande pgvector-tabellen).
De PRISM-index
PRISM (Partitioned Routing Index for Similarity Matching) is een PostgreSQL-native index-toegangsmethode. Conceptueel is het vergelijkbaar met de IVFFlat van pgvector, maar het is gebouwd rond state-of-the-art kwantisering, routing en partitioneringstechnieken. De implementatie is in C voor hoge prestaties en naadloze integratie met PostgreSQL.
Het resultaat is een index die significant sneller is dan de IVFFlat en HNSW van pgvector, zowel bij het uitvoeren van queries als bij het bouwen van de index. In vergelijking met de grafiekgebaseerde HNSW is PRISM sneller bij een gelijkwaardige recall op een dataset van 100 miljoen vectoren, terwijl er slechts een kwart van het geheugen nodig is op een instance.
Om deze prestaties te bereiken, gebruikt PRISM een hiërarchische centroid-boom om vectoren in clusters te verdelen, waarbij vertrouwd wordt op de PostgreSQL buffer cache om die boom in het geheugen te houden. Vectoren worden RaBitQ-gekwantiseerd en opgeslagen in posting lists met een paginalay-out die is geoptimaliseerd voor SIMD-afstandsberekeningen. De RaBitQ-codering bevat foutmarges waardoor een zoekopdracht vectoren kan uitsluiten die onmogelijk de dichtstbijzijnde buren kunnen zijn. Hierdoor hoeven er aanzienlijk minder vectoren opnieuw gerangschikt te worden tegen de volledige precisie-vectoren die in de tabel zijn opgeslagen.
Query-flow:
- Doorloop de centroid-boom om de dichtstbijzijnde clusters te vinden (buffer cache).
- Scan de posting lists voor kandidaten (buffer cache, async I/O).
- RaBitQ tweestapsfiltering: schatting → foutmarge → herrangschikking.
- Volledige precisie-herrangschikking vanuit de heap.
- Retourneer de $k$ dichtstbijzijnde buren.
Voor gedetailleerde architectuur, zie docs/architecture.md.
Gebruik
Installeer eerst de extensie (zie Installatie). Er zijn twee manieren om een PRISM-index te gebruiken, afhankelijk van waar uw vectoren zijn opgeslagen:
- Native types: Wanneer u opnieuw begint of geen gebruik maakt van
pgvector. Sla vectoren op in de eigen vec32 (float32) of vec16 (float16) kolommen van pg_vectorsearch. Er is geen andere extensie nodig.
- Bestaande pgvector-tabellen: Heeft u al
vector- of halfvec-kolommen? Installeer pg_vectorsearch naast pgvector en bouw een PRISM-index op deze kolommen zoals ze zijn. Uw tabel en queries blijven ongewijzigd.
Beide methoden bouwen dezelfde index en maken gebruik van dezelfde operatoren (<->, <#>, <=>) en instellingen.
Native types
CREATE EXTENSION pg_vectorsearch;
-- PLAIN houdt de vector inline. EXTERNAL (standaard) gebruikt TOAST voor
-- waarden boven ~2 kB, wat een extra fetch veroorzaakt die de planner niet meerekent.
CREATE TABLE items (
id serial PRIMARY KEY,
embedding vec32(3) STORAGE PLAIN
);
-- Laad eerst de data; de index wordt gebaseerd op het aantal rijen bij CREATE INDEX.
-- 500 rijen zijn voldoende om de planner de index te laten gebruiken.
INSERT INTO items (embedding)
SELECT ARRAY[i::real, (i % 7)::real, (i % 5)::real]::vec32
FROM generate_series(1, 1000) i;
-- Voor inner product of cosine, zie Operator-klassen hieronder.
CREATE INDEX ON items USING prism (embedding vec32_l2_ops);
-- 0 = auto (~0.95 recall). Verhoog voor recall, verlaag voor snelheid.
SET prism.nprobe = 40;
SELECT * FROM items
ORDER BY embedding <-> '[3,1,2]'
LIMIT 5;
Gebruik vec16 in plaats van vec32 om de ruimte die vectoren in de tabel innemen te halveren, in combinatie met de bijbehorende vec16_* operator-klassen.
Bestaande pgvector-tabellen
Als u al een tabel heeft met vector- of halfvec-kolommen van pgvector, kunt u hier direct een PRISM-index op bouwen. Niets aan de tabel of uw queries hoeft te veranderen.
vec32 en vec16 zijn binair compatibel met de vector en halfvec van pgvector, maar hebben andere namen. Hierdoor kunnen beide extensies naast elkaar worden geïnstalleerd, zelfs in hetzelfde schema.
-- De tabel die u al heeft (opgenomen zodat het voorbeeld zelfstandig werkt).
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);
-- Installeer pg_vectorsearch naast pgvector en bouw de index op de bestaande kolom.
-- De kolom wordt niet herschreven of gekopieerd.
CREATE EXTENSION pg_vectorsearch;
CREATE INDEX documents_embedding_prism
ON documents USING prism (embedding vec32_l2_ops);
-- Uw queries blijven werken zoals voorheen. PRISM is normaal gesproken sneller,
-- dus de planner zou de voorkeur moeten geven aan PRISM boven de HNSW-index.
-- Verifieer dit met EXPLAIN:
EXPLAIN (COSTS OFF)
SELECT id, body
FROM documents
ORDER BY embedding <-> (SELECT embedding FROM documents WHERE id = 42)
LIMIT 10;
-- Resultaat:
-- 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)
-- Zodra u tevreden bent, kunt u de HNSW-index verwijderen.
DROP INDEX documents_embedding_hnsw;
Gebruik de PRISM operator-klasse voor dezelfde afstandsmetriek als uw HNSW-index.
Operator-klassen
Kies de operator-klasse op basis van de afstandsmetriek en het kolomtype. L2 is de standaard.
| Afstand | Operator | vec32 / vector | vec16 / halfvec |
| L2 | <-> | vec32l2ops | vec16l2ops |
| Inner product | <#> | vec32ipops | vec16ipops |
| Cosine | <=> | vec32cosineops | vec16cosineops |
Bij het vervangen van een HNSW-index komt vector<metriek>ops van pgvector overeen met vec32<metriek>ops en halfvec<metriek>ops met vec16<metriek>ops.
Tuning
De standaardinstellingen zijn afgestemd op basis van grootschalige benchmarks; de meeste implementaties passen alleen prism.nprobe aan. Zie de tuning-gids voor elke indexparameter en GUC, hun trade-offs en wanneer het zinvol is om ze te wijzigen.
Onderhoud
Een insert voegt gegevens toe aan de posting list waar de vector naartoe wordt gerouteerd. Hierdoor groeien lijsten naarmate er rijen worden toegevoegd, maar splitsen ze nooit automatisch. Naast REINDEX splitst de procedure prism_rebalance te grote lijsten in place. Zie de onderhoudsgids voor de werking en huidige beperkingen.
Installatie
Vereisten:
- PostgreSQL 18+ (met development headers)
- GNU C11 compiler (GCC 11+ of Clang 14+)
- Meson build system
- Optioneel: CBLAS, voor snellere RaBitQ-codering.
Build stappen:
# Release build
meson setup builddir --buildtype=release
# Build en installatie naar PostgreSQL
meson install -C builddir
Zie de development-gids voor aanvullende build-opties.
Documentatie
- Tuning - Indexparameters, GUC's, trade-offs, standaarden.
- Onderhoud - Rebalancing en het splitsen van posting-lijsten.
- Architectuur - High-level design en datastructuren.
- SIMD - SIMD build-opties en afstandsberekening.
- Development - Build-opties, testen, CI-scripts.
Referenties
Onderzoek
- 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)
Gerelateerde Projecten
- pgvector - Vector type en operatoren voor PostgreSQL.
- pgvectorscale - DiskANN-gebaseerde vector index voor PostgreSQL.
Licentie
The PostgreSQL License