~/tools / Embeddings und Suche (RAG) / pgvector SQL Builder

pgvector SQL Builder — pgvector-SQL: Tabelle, HNSW/IVFFlat-Index und Abfrage nach nächsten Nachbarn

Schreiben Sie das SQL, um Embeddings in PostgreSQL mit pgvector zu speichern und zu durchsuchen: eine Tabelle mit einer Spalte vector(n) oder halfvec(n), einen HNSW- oder IVFFlat-Index mit der zu Ihrem Abstand passenden Operatorklasse und eine Abfrage nach den nächsten Nachbarn mit gut lesbarem Score. Das Tool prüft die in der pgvector-Dokumentation genannten Grenzen und schätzt, wie viel Platz die Vektoren belegen. Nichts verlässt Ihren Browser.

Jeder Vektor belegt 1,544 Bytes, daher belegen 10,000 Zeilen allein für die Vektoren etwa 15.4 MB (Indizes und andere Spalten nicht eingerechnet).

1. Erweiterung und Tabelle

CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE documents (
  id bigserial PRIMARY KEY,
  content text NOT NULL,
  embedding vector(384) NOT NULL
);

2. Index

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

3. Suche

PREPARE erwartet den Vektor der Frage aus /api/embed als $1. Übergeben Sie ihn als Text, etwa '[0.01,-0.02,…]'.

PREPARE search_documents(vector(384)) AS
  SELECT id, content, 1 - (embedding <=> $1) AS cosine_similarity
  FROM documents
  ORDER BY embedding <=> $1
  LIMIT 5;

-- EXECUTE search_documents('[0.0123, -0.0456, ...]');

Grenzen und Standardwerte aus der pgvector-0.8.7-README und dem Quellcode, geprüft am 2026-11-04. pgvector README

Alles geschieht in Ihrem Browser. Das Tool schreibt SQL und verbindet sich mit nichts.

pgvector ist eine Open-Source-Erweiterung, die PostgreSQL um die Ähnlichkeitssuche für Vektoren ergänzt, sodass die Embeddings, die Sie mit Ollama erzeugen, in derselben Datenbank wie Ihre übrigen Daten gespeichert werden können. Einige Details sind leicht falsch zu machen. Die Spalte muss dieselbe Anzahl von Dimensionen haben wie Ihr Embedding-Modell. Jeder Abstand hat seinen eigenen Operator: <=> für den Kosinus-Abstand, <-> für den L2-Abstand, <#> für das negative Skalarprodukt und <+> für den L1-Abstand. Ein approximativer Index wird nur verwendet, wenn er mit der Operatorklasse für denselben Abstand gebaut wurde, etwa vector_cosine_ops für <=>, und wenn die Abfrage nach dem Operator selbst in aufsteigender Reihenfolge sortiert und ein LIMIT enthält. Dieses Tool schreibt die drei Teile aus einer einzigen Auswahl: CREATE EXTENSION und CREATE TABLE, CREATE INDEX sowie eine PREPARE-Anweisung, die die nächsten Zeilen mit einem gut lesbaren Score zurückgibt (die Kosinus-Ähnlichkeit ist 1 minus der Kosinus-Abstand, und das Skalarprodukt ist <#> multipliziert mit -1). Es wendet die Grenzen aus der pgvector-README und dem Quellcode für Version 0.8.7 an: bis zu 16,000 Dimensionen in einer Spalte, Indizes bis 2,000 Dimensionen für vector und 4,000 für halfvec, keine L1-Operatorklasse für IVFFlat, bei HNSW m von 2 bis 100 und ef_construction von 4 bis 1,000 sowie mindestens 2 × m. Bei HNSW liefert eine Suche höchstens hnsw.ef_search Zeilen (standardmäßig 40), daher warnt das Tool, wenn LIMIT größer ist. Für IVFFlat trägt es lists und probes nach den Ausgangswerten der README ein: rows / 1000 bis 1M Zeilen, darüber sqrt(rows), und sqrt(lists) für probes. Das erzeugte SQL wurde mit pgvector 0.8.7 und PostgreSQL 16 mit echten Vektoren mit 384 Dimensionen von Ollama ausgeführt, und EXPLAIN zeigte, dass der Index verwendet wurde.

Die Kernlogik dieses Tools ist Open Source unter der MIT-Lizenz. github.com/seigo5555/toolkitbox-lib/src/pgvector-sql.ts

Anwendungsfälle

  • Die Tabelle für Ihre Textabschnitte anlegen, bevor Sie Embeddings von Ollama in PostgreSQL laden
  • Prüfen, welcher Operator zu welcher Operatorklasse für Kosinus-, L2-, Skalarprodukt- oder L1-Abstand gehört, damit der Index auch wirklich verwendet wird
  • Abschätzen, wie viel Platz die Vektoren auf einem kleinen VPS belegen, und vector mit halfvec vergleichen

Verwendung

  1. Geben Sie den Tabellennamen und die Anzahl der Dimensionen Ihres Embedding-Modells ein. Das ist die Länge eines Vektors aus /api/embed; der Embedding Similarity Calculator auf dieser Website zeigt sie an.
  2. Wählen Sie den Typ, den Abstand und den Index. Die Dokumentation von Ollama empfiehlt die Kosinus-Ähnlichkeit für die meisten Fälle der semantischen Suche, und /api/embed liefert Vektoren mit der Länge 1.
  3. Kopieren Sie die drei Blöcke und führen Sie sie in psql oder einem anderen Client aus. Legen Sie einen IVFFlat-Index an, nachdem die Daten geladen sind; ein HNSW-Index kann auf einer leeren Tabelle angelegt werden.

FAQ

Welchen Abstand soll ich wählen?

Die Embeddings-Dokumentation von Ollama empfiehlt die Kosinus-Ähnlichkeit für die meisten Fälle der semantischen Suche. In pgvector liefert <=> den Kosinus-Abstand, und das Tool macht daraus cosine_similarity mit 1 minus dem Abstand. Bei Vektoren mit der Länge 1, wie sie /api/embed liefert, bringen Kosinus-Abstand, L2-Abstand und Skalarprodukt die Zeilen in dieselbe Reihenfolge, weil für solche Vektoren der quadrierte L2-Abstand 2 minus 2 mal die Kosinus-Ähnlichkeit ist.

HNSW oder IVFFlat?

Die pgvector-README sagt, dass HNSW eine bessere Abfrageleistung als IVFFlat hat (im Sinne des Kompromisses zwischen Geschwindigkeit und Recall), sich aber langsamer aufbaut und mehr Speicher braucht, und dass er auf einer leeren Tabelle angelegt werden kann, weil es keinen Trainingsschritt gibt. IVFFlat baut sich schneller auf, braucht weniger Speicher und sollte angelegt werden, nachdem die Tabelle einige Daten enthält. Ohne Index führt pgvector eine exakte Suche durch, die einen perfekten Recall liefert.

Warum verwendet meine Abfrage den Index nicht?

Laut README braucht die Abfrage ORDER BY und LIMIT, und das ORDER BY muss der Abstandsoperator selbst in aufsteigender Reihenfolge sein, kein Ausdruck wie 1 - (embedding <=> …) DESC. Der Operator muss außerdem zur Operatorklasse des Index passen: <=> mit vector_cosine_ops, <-> mit vector_l2_ops, <#> mit vector_ip_ops und <+> mit vector_l1_ops. Das Tool schreibt beides aus derselben Auswahl. Die README merkt außerdem an, dass ein Table Scan bei kleinen Tabellen schneller sein kann.

Warum bekomme ich weniger Zeilen als LIMIT?

Bei HNSW werden die Ergebnisse durch hnsw.ef_search begrenzt, standardmäßig 40; als wir LIMIT 100 auf einer Tabelle mit 200 Zeilen ausprobierten, erhielten wir 40 Zeilen, bis wir hnsw.ef_search auf 100 erhöhten. Die README fügt hinzu, dass die Filterung mit WHERE nach dem Durchsuchen des Index erfolgt, sodass eine Bedingung noch weniger Zeilen übrig lassen kann. Seit Version 0.8.0 durchsuchen iterative Indexscans (SET hnsw.iterative_scan = strict_order oder relaxed_order) bei Bedarf mehr vom Index.

Was ist halfvec?

Ein Vektortyp mit halber Genauigkeit. Jeder Vektor belegt 2 × Dimensionen + 8 Bytes statt 4 × Dimensionen + 8, und HNSW- und IVFFlat-Indizes auf halfvec unterstützen bis zu 4,000 statt 2,000 Dimensionen. Jedes Element ist eine Gleitkommazahl mit halber Genauigkeit, die Werte werden also weniger genau gespeichert.

Werden meine Daten irgendwohin gesendet?

Nein. Das Tool schreibt das SQL nur in Ihrem Browser und verbindet sich nie mit einer Datenbank.

Passende Artikel

Ähnliche Tools