Aller au contenu
Expérimentation

pgvector vs Qdrant : rappel et latence de la recherche filtrée par ACL

Mesurer la perte de rappel et la latence d'une recherche vectorielle filtrée par dossier_id (10 %, 30 %, 100 % de portée) avec pgvector HNSW (sans et avec iterative_scan, RLS) et Qdrant (payload is_tenant, JWT payload).

Hypothèse#rag#vector-db#pgvector#qdrant#permissions#benchmarkPublié le 16 sept. 2026Mis à jour le 16 sept. 2026
Statut du test
À tester
Priorité
Haute
Prévu pour
Octobre 2026
Hypothèse
Avec hnsw.iterative_scan activé, pgvector conserve au moins 90 % du rappel non filtré pour un utilisateur ayant accès à 10 % des dossiers, à une latence inférieure à 200 ms ; Qdrant y parvient sans réglage grâce au filtrage intégré à HNSW. Dans les deux cas, la barrière moteur (RLS, JWT payload) ne renvoie aucun point hors portée.
Procédure
Corpus synthétique de 1 million de chunks (1 024 dims) répartis sur 200 dossiers. 100 requêtes. Mesurer recall@20 (contre une recherche exacte) et latence p95 pour des portées de 10 %, 30 %, 100 % : pgvector HNSW défaut ; pgvector + iterative_scan relaxed_order ; pgvector + index partiels ; pgvector + RLS active ; pgvectorscale ; Qdrant collection unique payload is_tenant ; Qdrant avec JWT payload. Vérifier zéro point hors portée avec la barrière moteur seule.

Pourquoi

C'est le test qui tranche Q-004. pgvector documente que « With approximate indexes, filtering is applied after the index is scanned. If a condition matches 10% of rows, with HNSW and the default hnsw.ef_search of 40, only 4 rows will match on average », et propose depuis 0.8.0 les « iterative index scans » 1. Qdrant intègre le filtre payload à HNSW et regroupe les points par tenant avec is_tenant 3. Le filtre ACL est précisément ce cas : un avocat voit une fraction des dossiers.

Protocole

  1. Générer 1 million de chunks synthétiques (texte aléatoire vectorisé par le modèle retenu, ou vecteurs synthétiques) sur 200 dossiers de tailles inégales.
  2. Calculer la vérité terrain par recherche exacte (scan complet) pour 100 requêtes et 3 portées (10 %, 30 %, 100 % des dossiers).
  3. pgvector : HNSW m=16, ef_construction=64 ; ef_search 40 puis 100 ; hnsw.iterative_scan = off | relaxed_order | strict_order ; index B-tree sur dossier_id ; variante index partiels ; variante RLS active avec rôle non superuser et SET LOCAL app.user_id 2 ; lire le plan d'exécution pour vérifier l'ordre filtre / distance.
  4. pgvectorscale : même jeu avec StreamingDiskANN et filtre par labels 5.
  5. Qdrant : collection unique, payload dossier_id indexé is_tenant: true ; variante payload_m: 16, m: 0 ; variante JWT avec claim payload 4.
  6. Mesurer recall@20 et latence p95, mémoire résidente, temps de construction de l'index.
  7. Barrière seule : requêtes sans filtre applicatif, avec RLS ou JWT seulement : zéro point hors portée attendu.

Critères

Rappel filtré à 10 % supérieur ou égal à 90 % du rappel non filtré ; latence p95 inférieure à 200 ms ; zéro point hors portée avec la barrière moteur seule. Si pgvector satisfait les trois, il est retenu (une seule base à exploiter) ; sinon Qdrant.

Résultat

À venir.

Sources

  1. 1pgvector — README (filtrage, HNSW, iterative scan 0.8.0)GitHubFiabilité hautepgvector · publié v0.8.6 (README) ; 0.8.0 annoncé sur postgresql.org · consulté le 16 sept. 2026 · fiche source
  2. 2PostgreSQL — Row Security Policies (RLS)Documentation officielleFiabilité hautePostgreSQL · publié documentation courante · consulté le 16 sept. 2026 · fiche source
  3. 3Qdrant — Multitenancy (payload partitioning, is_tenant)Documentation officielleFiabilité hauteQdrant · publié lu le 16/09/2026 · consulté le 16 sept. 2026 · fiche source
  4. 4Qdrant — Security (API key, TLS, JWT avec claim payload)Documentation officielleFiabilité hauteQdrant · publié lu le 16/09/2026 ; RBAC JWT introduit en 1.9.0 (blog du 24/04/2024) · consulté le 16 sept. 2026 · fiche source
  5. 5pgvectorscale — README (StreamingDiskANN, filtered search)GitHubFiabilité moyenneTimescale · publié lu le 16/09/2026 · consulté le 16 sept. 2026 · fiche source
content/experiments/pgvector-vs-qdrant-filtrage-acl.md305 mots