~/tools / Embeddings et recherche (RAG) / pgvector SQL Builder
pgvector SQL Builder — Écrivez du SQL pgvector : table, index HNSW/IVFFlat et requête de voisins
Écrivez le SQL pour stocker et rechercher des embeddings dans PostgreSQL avec pgvector : une table avec une colonne vector(n) ou halfvec(n), un index HNSW ou IVFFlat avec la classe d'opérateurs qui correspond à votre distance, et une requête de plus proches voisins avec un score lisible. L'outil vérifie les limites indiquées dans la documentation de pgvector et estime la place qu'occupent les vecteurs. Rien ne quitte votre navigateur.
Chaque vecteur occupe 1,544 octets, donc 10,000 lignes occupent environ 15.4 MB pour les seuls vecteurs (index et autres colonnes non inclus).
1. Extension et table
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. Recherche
PREPARE reçoit comme $1 le vecteur de la question obtenu avec /api/embed. Passez-le sous forme de texte, par exemple '[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, ...]');Limites et valeurs par défaut issues du README et du code source de pgvector 0.8.7, vérifiées le 2026-11-04. README de pgvector
Tout se passe dans votre navigateur. L'outil écrit du SQL et ne se connecte à rien.
pgvector est une extension open source qui ajoute à PostgreSQL la recherche par similarité de vecteurs, de sorte que les embeddings que vous créez avec Ollama peuvent être stockés dans la même base de données que le reste de vos données. Plusieurs détails sont faciles à rater. La colonne doit avoir le même nombre de dimensions que votre modèle d'embeddings. Chaque distance a son propre opérateur : <=> pour la distance cosinus, <-> pour la distance L2, <#> pour le produit scalaire négatif et <+> pour la distance L1. Un index approximatif n'est utilisé que s'il a été créé avec la classe d'opérateurs de la même distance, comme vector_cosine_ops pour <=>, et si la requête trie selon l'opérateur lui-même, en ordre croissant, avec un LIMIT. Cet outil écrit les trois parties à partir d'un seul ensemble de choix : CREATE EXTENSION et CREATE TABLE, CREATE INDEX, et une instruction PREPARE qui renvoie les lignes les plus proches avec un score lisible (la similarité cosinus vaut 1 moins la distance cosinus, et le produit scalaire vaut <#> multiplié par -1). Il applique les limites du README et du code source de pgvector pour la version 0.8.7 : jusqu'à 16,000 dimensions dans une colonne, des index jusqu'à 2,000 dimensions pour vector et 4,000 pour halfvec, pas de classe d'opérateurs L1 pour IVFFlat, m de HNSW de 2 à 100, et ef_construction de 4 à 1,000 et au moins égal à 2 × m. Avec HNSW, une recherche renvoie au plus hnsw.ef_search lignes (40 par défaut), donc l'outil avertit quand LIMIT est plus grand. Pour IVFFlat, il renseigne lists et probes avec les points de départ du README : rows / 1000 jusqu'à 1M de lignes, sqrt(rows) au-delà, et sqrt(lists) pour probes. Le SQL généré a été exécuté sur pgvector 0.8.7 avec PostgreSQL 16, à partir de vrais vecteurs de 384 dimensions d'Ollama, et EXPLAIN a montré que l'index était utilisé.
Le cœur de cet outil est open source, sous licence MIT. github.com/seigo5555/toolkitbox-lib/src/pgvector-sql.ts
Cas d'usage
- Créer la table pour les fragments de vos documents avant de charger dans PostgreSQL les embeddings d'Ollama
- Vérifier quel opérateur va avec quelle classe d'opérateurs pour la distance cosinus, L2, le produit scalaire ou L1, afin que l'index soit réellement utilisé
- Estimer la place qu'occupent les vecteurs sur un petit VPS et comparer vector et halfvec
Utilisation
- Saisissez le nom de la table et le nombre de dimensions de votre modèle d'embeddings. C'est la longueur d'un vecteur de /api/embed ; l'Embedding Similarity Calculator de ce site l'affiche.
- Choisissez le type, la distance et l'index. La documentation d'Ollama recommande la similarité cosinus pour la plupart des recherches sémantiques, et /api/embed renvoie des vecteurs de longueur 1.
- Copiez les trois blocs et exécutez-les dans psql ou un autre client. Créez un index IVFFlat après le chargement des données ; un index HNSW peut être créé sur une table vide.
FAQ
Quelle distance dois-je choisir ?
La documentation des embeddings d'Ollama recommande la similarité cosinus pour la plupart des cas de recherche sémantique. Dans pgvector, <=> renvoie la distance cosinus, et l'outil la transforme en cosine_similarity avec 1 moins la distance. Pour des vecteurs de longueur 1, comme ceux de /api/embed, la distance cosinus, la distance L2 et le produit scalaire classent les lignes dans le même ordre, car pour de tels vecteurs le carré de la distance L2 vaut 2 moins 2 fois la similarité cosinus.
HNSW ou IVFFlat ?
Le README de pgvector indique que HNSW offre de meilleures performances de requête qu'IVFFlat (en termes de compromis entre vitesse et rappel), mais qu'il se construit plus lentement et utilise plus de mémoire, et qu'il peut être créé sur une table vide car il n'y a pas d'étape d'entraînement. IVFFlat se construit plus vite, utilise moins de mémoire et doit être créé une fois que la table contient des données. Sans index, pgvector effectue une recherche exacte, qui donne un rappel parfait.
Pourquoi ma requête n'utilise-t-elle pas l'index ?
Le README indique que la requête a besoin de ORDER BY et de LIMIT, et que l'ORDER BY doit être l'opérateur de distance lui-même, en ordre croissant, et non une expression comme 1 - (embedding <=> …) DESC. L'opérateur doit aussi correspondre à la classe d'opérateurs de l'index : <=> avec vector_cosine_ops, <-> avec vector_l2_ops, <#> avec vector_ip_ops et <+> avec vector_l1_ops. L'outil écrit les deux à partir du même choix. Le README note aussi qu'un parcours de la table peut être plus rapide quand la table est petite.
Pourquoi ai-je moins de lignes que LIMIT ?
Avec HNSW, les résultats sont limités par hnsw.ef_search, qui vaut 40 par défaut ; quand nous avons essayé LIMIT 100 sur une table de 200 lignes, nous avons obtenu 40 lignes jusqu'à ce que nous augmentions hnsw.ef_search à 100. Le README ajoute que le filtrage avec WHERE est appliqué après le parcours de l'index, donc une condition peut laisser encore moins de lignes. Depuis la version 0.8.0, les parcours itératifs de l'index (SET hnsw.iterative_scan = strict_order ou relaxed_order) parcourent une plus grande partie de l'index quand c'est nécessaire.
Qu'est-ce que halfvec ?
Un type de vecteur en demi-précision. Chaque vecteur occupe 2 × dimensions + 8 octets au lieu de 4 × dimensions + 8, et les index HNSW et IVFFlat sur halfvec prennent en charge jusqu'à 4,000 dimensions au lieu de 2,000. Chaque élément est un nombre à virgule flottante en demi-précision, donc les valeurs sont stockées avec moins de précision.
Mes données sont-elles envoyées quelque part ?
Non. L'outil se contente d'écrire du SQL dans votre navigateur et ne se connecte jamais à une base de données.
Articles liés
- Stocker et rechercher des embeddings Ollama dans PostgreSQL avec pgvectorConservez des embeddings Ollama dans PostgreSQL avec pgvector, recherchez-les avec HNSW ou IVFFlat, et transmettez les résultats à /api/chat pour que la réponse cite ses sources.
- Embeddings avec Ollama : les bases pour la recherche et le RAGCréez des embeddings avec le /api/embed d'Ollama : les modèles et leurs tailles, truncate et dimensions, vecteurs de longueur unitaire et similarité cosinus, d'après la documentation officielle.