~/tools / Embedding e ricerca (RAG) / pgvector SQL Builder
pgvector SQL Builder — Scrivi SQL per pgvector: tabella, indice HNSW/IVFFlat e query dei vicini
Scrivi l'SQL per salvare e cercare embedding in PostgreSQL con pgvector: una tabella con una colonna vector(n) o halfvec(n), un indice HNSW o IVFFlat con la classe di operatori che corrisponde alla tua distanza e una query dei vicini più prossimi con un punteggio leggibile. Controlla i limiti indicati nella documentazione di pgvector e stima quanto spazio occupano i vettori. Nulla lascia il tuo browser.
Ogni vettore occupa 1,544 byte, quindi 10,000 righe occupano circa 15.4 MB per i soli vettori (indici e altre colonne esclusi).
1. Estensione e tabella
CREATE EXTENSION IF NOT EXISTS vector; CREATE TABLE documents ( id bigserial PRIMARY KEY, content text NOT NULL, embedding vector(384) NOT NULL );
2. Indice
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);
3. Ricerca
PREPARE riceve come $1 il vettore della domanda ottenuto da /api/embed. Passalo come testo, per esempio '[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, ...]');Limiti e valori predefiniti dal README e dal codice sorgente di pgvector 0.8.7, verificati il 2026-11-04. README di pgvector
Tutto avviene nel tuo browser. Lo strumento scrive SQL e non si connette a nulla.
pgvector è un'estensione open source che aggiunge a PostgreSQL la ricerca per similarità di vettori, così gli embedding che crei con Ollama possono essere salvati nello stesso database del resto dei tuoi dati. Alcuni dettagli sono facili da sbagliare. La colonna deve avere lo stesso numero di dimensioni del tuo modello di embedding. Ogni distanza ha il proprio operatore: <=> per la distanza del coseno, <-> per la distanza L2, <#> per il prodotto interno negativo e <+> per la distanza L1. Un indice approssimato viene usato solo se è stato creato con la classe di operatori della stessa distanza, come vector_cosine_ops per <=>, e se la query ordina per l'operatore stesso in ordine crescente con un LIMIT. Questo strumento scrive le tre parti a partire da un unico insieme di scelte: CREATE EXTENSION e CREATE TABLE, CREATE INDEX, e un'istruzione PREPARE che restituisce le righe più vicine con un punteggio leggibile (la similarità del coseno è 1 meno la distanza del coseno, e il prodotto interno è <#> moltiplicato per -1). Applica i limiti del README e del codice sorgente di pgvector per la versione 0.8.7: fino a 16,000 dimensioni in una colonna, indici fino a 2,000 dimensioni per vector e 4,000 per halfvec, nessuna classe di operatori L1 per IVFFlat, m di HNSW da 2 a 100, ed ef_construction da 4 a 1,000 e almeno 2 × m. Con HNSW, una ricerca restituisce al massimo hnsw.ef_search righe (40 per impostazione predefinita), quindi lo strumento avvisa quando LIMIT è maggiore. Per IVFFlat compila lists e probes con i punti di partenza del README: rows / 1000 fino a 1M righe, sqrt(rows) oltre, e sqrt(lists) per probes. L'SQL generato è stato eseguito su pgvector 0.8.7 con PostgreSQL 16 usando vettori reali a 384 dimensioni di Ollama, ed EXPLAIN ha mostrato che l'indice veniva usato.
La logica principale di questo strumento è open source, con licenza MIT. github.com/seigo5555/toolkitbox-lib/src/pgvector-sql.ts
Casi d'uso
- Creare la tabella per i frammenti dei tuoi documenti prima di caricare in PostgreSQL gli embedding di Ollama
- Controllare quale operatore va con quale classe di operatori per la distanza del coseno, L2, il prodotto interno o L1, in modo che l'indice venga davvero usato
- Stimare quanto spazio occupano i vettori su un piccolo VPS e confrontare vector e halfvec
Utilizzo
- Inserisci il nome della tabella e il numero di dimensioni del tuo modello di embedding. È la lunghezza di un vettore di /api/embed; l'Embedding Similarity Calculator di questo sito la mostra.
- Scegli il tipo, la distanza e l'indice. La documentazione di Ollama consiglia la similarità del coseno per la maggior parte delle ricerche semantiche, e /api/embed restituisce vettori di lunghezza 1.
- Copia i tre blocchi ed eseguili in psql o in un altro client. Crea un indice IVFFlat dopo aver caricato i dati; un indice HNSW si può creare su una tabella vuota.
FAQ
Quale distanza devo scegliere?
La documentazione degli embedding di Ollama consiglia la similarità del coseno per la maggior parte dei casi di ricerca semantica. In pgvector, <=> restituisce la distanza del coseno, e lo strumento la trasforma in cosine_similarity con 1 meno la distanza. Per vettori di lunghezza 1, come quelli di /api/embed, la distanza del coseno, la distanza L2 e il prodotto interno ordinano le righe allo stesso modo, perché per tali vettori il quadrato della distanza L2 è 2 meno 2 volte la similarità del coseno.
HNSW o IVFFlat?
Il README di pgvector dice che HNSW ha prestazioni di query migliori di IVFFlat (in termini di compromesso tra velocità e recall), ma si costruisce più lentamente e usa più memoria, e che si può creare su una tabella vuota perché non c'è un passo di addestramento. IVFFlat si costruisce più velocemente, usa meno memoria e va creato dopo che la tabella contiene dei dati. Senza indice, pgvector esegue una ricerca esatta, che dà un recall perfetto.
Perché la mia query non usa l'indice?
Il README dice che la query ha bisogno di ORDER BY e LIMIT, e che l'ORDER BY deve essere l'operatore di distanza stesso in ordine crescente, non un'espressione come 1 - (embedding <=> …) DESC. L'operatore deve anche corrispondere alla classe di operatori dell'indice: <=> con vector_cosine_ops, <-> con vector_l2_ops, <#> con vector_ip_ops e <+> con vector_l1_ops. Lo strumento scrive entrambi a partire dalla stessa scelta. Il README osserva anche che una scansione della tabella può essere più veloce quando la tabella è piccola.
Perché ottengo meno righe di LIMIT?
Con HNSW, i risultati sono limitati da hnsw.ef_search, che è 40 per impostazione predefinita; quando abbiamo provato LIMIT 100 su una tabella di 200 righe, abbiamo ottenuto 40 righe finché non abbiamo alzato hnsw.ef_search a 100. Il README aggiunge che il filtraggio con WHERE viene applicato dopo la scansione dell'indice, quindi una condizione può lasciare ancora meno righe. Dalla versione 0.8.0, le scansioni iterative dell'indice (SET hnsw.iterative_scan = strict_order oppure relaxed_order) scorrono più parte dell'indice quando serve.
Che cos'è halfvec?
Un tipo di vettore a mezza precisione. Ogni vettore occupa 2 × dimensioni + 8 byte invece di 4 × dimensioni + 8, e gli indici HNSW e IVFFlat su halfvec supportano fino a 4,000 dimensioni invece di 2,000. Ogni elemento è un numero a virgola mobile a mezza precisione, quindi i valori sono memorizzati con meno precisione.
I miei dati vengono inviati da qualche parte?
No. Lo strumento si limita a scrivere SQL nel tuo browser e non si connette mai a un database.
Articoli correlati
- Salvare e cercare gli embedding di Ollama in PostgreSQL con pgvectorConserva gli embedding di Ollama in PostgreSQL con pgvector, cercali con HNSW o IVFFlat e passa i risultati a /api/chat perché la risposta citi le sue fonti.
- Embedding con Ollama: le basi per ricerca e RAGCrea embedding con l'/api/embed di Ollama: i modelli e le loro dimensioni, truncate e dimensions, vettori di lunghezza unitaria e similarità del coseno, secondo la documentazione ufficiale.