Vector Databases

Optimiser les performances de pgvector : Stratégies d'indexation et réglage des requêtes pour les charges de production

L'intégration des capacités de recherche vectorielle dans PostgreSQL via pgvector a démocratisé le déploiement de systèmes de Génération Augmentée par Récupération (RAG) et d'applications de recherche par similarité. Cependant, le passage d'un prototype de preuve de concept à un environnement de production à haut débit révèle souvent des goulets d'étranglement de performance. Une implémentation naïve peut entraîner des requêtes lentes, une latence élevée et une charge CPU inutile. Cet article explore comment optimiser les performances de pgvector grâce à des stratégies d'indexation intelligentes et au réglage des requêtes.

Comprendre le paysage de l'indexation

pgvector prend actuellement en charge deux méthodes d'indexation principales : HNSW (Hierarchical Navigable Small World) et IVFFlat (Inverted File with Flat Quantization). Choisir le bon index est la décision la plus impactante que vous puissiez prendre pour la performance.

HNSW est généralement recommandé pour la plupart des cas d'utilisation en production. Il offre des taux de rappel supérieurs et des temps de requête plus rapides par rapport à IVFFlat, en particulier à mesure que la taille de l'ensemble de données augmente. Bien qu'il consomme plus de mémoire et prenne plus de temps à être construit, sa capacité à naviguer efficacement dans la structure du graphe le rend idéal pour les exigences de faible latence. En revanche, IVFFlat est plus léger en mémoire et se construit plus rapidement, mais nécessite plus d'E/S disque et offre généralement un rappel inférieur, sauf si le nombre de listes est considérablement augmenté. Il convient mieux aux scénarios où la mémoire est limitée ou où les ensembles de données sont statiques et de taille modérée.

Création d'index optimisés

Lors de la création d'un index, le choix de la métrique de distance et des paramètres spécifiques dicte la qualité de la recherche. Pour les embeddings de texte dérivés de modèles comme BERT ou text-embedding-3-small d'OpenAI, la distance cosinus est souvent la norme. Voici comment créer un index HNSW optimisé :


CREATE INDEX CONCURRENTLY embedding_idx 
ON documents 
USING hnsw (embedding vector_cosine_ops);

Cependant, les paramètres par défaut sont rarement optimaux pour la production. Le paramètre m contrôle le nombre de liens bidirectionnels créés lors de la construction du graphe, tandis que ef_construction influence la qualité de la recherche lors de la construction de l'index. Pour des résultats de haute qualité, envisagez d'augmenter ef_construction :


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

Des valeurs plus élevées pour m et ef_construction augmentent l'utilisation de la mémoire et le temps de construction, mais améliorent considérablement la précision du rappel.

Réglage des performances des requêtes

Même avec un index bien optimisé, les performances des requêtes peuvent se dégrader si les paramètres de recherche ne sont pas ajustés. Le paramètre hnsw_ef_search agit comme un budget pour l'algorithme de recherche. Par défaut, il est défini sur 40, ce qui équilibre vitesse et précision. Pour les charges de production, vous devez ajuster cette valeur en fonction de la latence acceptable et du rappel souhaité.

Si vous rencontrez une latence p99 élevée, essayez de réduire hnsw_ef_search. Si votre application nécessite une précision de récupération quasi parfaite, augmentez-la. Vous pouvez définir cela au niveau de la session :


SET hnsw.ef_search = 128;
SELECT * 
FROM documents 
ORDER BY embedding <#> '[0.1, 0.2, ..., 0.1]'::vector
LIMIT 10;

Considérations pratiques à grande échelle

À mesure que votre ensemble de données dépasse les centaines de millions de vecteurs, envisagez de partitionner vos tables par une colonne non vectorielle, telle qu'un ID de locataire ou une date. Cela vous permet de créer des index plus petits et plus ciblés, réduisant ainsi la surcharge de la traversal du graphe. De plus, assurez-vous que votre serveur de base de données dispose d'une mémoire partagée suffisante (shared_buffers) et que les paramètres de niveau WAL sont configurés pour gérer la charge d'écriture lourde associée à la construction des index.

Conclusion

L'optimisation de pgvector n'est pas une configuration unique, mais un processus itératif. Commencez par HNSW pour son profil de performance équilibré, réglez ef_construction et ef_search pour correspondre à vos SLA de latence et de précision, et surveillez les compromis entre l'utilisation de la mémoire et la vitesse des requêtes. En appliquant ces stratégies, vous pouvez tirer parti de la puissance de la recherche vectorielle au sein de PostgreSQL sans compromettre les performances ou la fiabilité.

Share: