- La Full-Text Search (FTS) native de PostgreSQL a la réputation d’être lente, mais avec une optimisation adaptée, elle peut être très rapide
- Le blog de Neon compare l’extension
pg_search basée sur Rust à la FTS native et affirme que cette dernière est lente
- Mais cette comparaison a probablement été réalisée en omettant des optimisations de base indispensables à la FTS de PostgreSQL
- Cet article démontre chiffres à l’appui qu’une simple optimisation de la configuration FTS native peut apporter un gain de performances de 50x
Aperçu de la configuration du benchmark
- Test réalisé sur une table contenant 10 millions de lignes de logs
CREATE TABLE benchmark_logs (
id SERIAL PRIMARY KEY,
message TEXT,
country VARCHAR(255),
severity INTEGER,
timestamp TIMESTAMP,
metadata JSONB
);
- Structure de la requête problématique :
SELECT country, COUNT(*)
FROM benchmark_logs
WHERE to_tsvector('english', message) @@ to_tsquery('english', 'research')
GROUP BY country
ORDER BY country;
- Exécution de
to_tsvector() dans la requête → très inefficace
- Même avec un index GIN, il n’est pas correctement exploité
Environnement de test (reproduction de la configuration de base)
Facteur de dégradation n°1 : calcul de tsvector en temps réel
Facteur de dégradation n°2 : fastupdate=on sur l’index GIN
Gains de performance : plus de 50x d’amélioration
- Avant optimisation : environ 41,3 s (41 301 ms)
- Après optimisation : environ 0,88 s (877 ms)
- Soit un gain de performances d’environ 50x
- Ce niveau de performance est atteignable même dans un environnement peu parallélisé
Les performances de ts_rank peuvent effectivement être lentes
ts_rank ou ts_rank_cd peuvent être relativement lents, car ils évaluent tous les résultats avant de les trier
- En particulier sur de gros volumes de résultats, la charge CPU/IO peut être importante
Fonctionnalité de ranking avancée : extension VectorChord-BM25
- Lorsque la précision du tri et la vitesse sont critiques, il peut être plus efficace d’utiliser une extension dédiée
- VectorChord-BM25 est une extension pour PostgreSQL qui fournit une évaluation du ranking basée sur l’algorithme BM25
- Certains retours indiquent qu’elle peut être 3x plus rapide qu’Elasticsearch
Avantages de VectorChord-BM25
- Algorithme BM25 : un algorithme de ranking de recherche plus avancé que TF-IDF
- Format d’index dédié : optimisé pour la recherche rapide avec notamment Block WeakAnd
- Fournit le type
bm25vector : stockage d’une représentation tokenisée
- Améliore à la fois la précision de recherche et la vitesse
Conclusion : la FTS native de PostgreSQL est largement assez rapide
- Avec une colonne
tsvector et un index GIN approprié (fastupdate=off), la FTS native permet déjà des recherches très rapides
- Les comparaisons de performances doivent se faire sur une base correctement optimisée
- Si des fonctions de ranking avancées sont nécessaires, on peut envisager des extensions comme VectorChord-BM25
- Message clé : ce n’est pas l’outil qui est lent, c’est parfois la configuration qui pose problème
3 commentaires
Grâce à cela, j’ai fait du tuning de requête.
Les réactions sur Hacker News font peur... « Dix millions ? Une blague ? »
Avis Hacker News
En tant que mainteneur de
pg_search, selon la documentation Postgres, l’article de Neon/ParadeDB et la stratégie utilisée ici sont tous deux présentés comme des alternatives validespg_searcha été conçu pour résoudre ce second problème, et les benchmarks le reflètent égalementpg_searchfonctionne sur une variété de requêtes de style « Elastic » et de types Postgres avec une simple définition d’indexCalculer
tsvectoren temps réel est une grosse erreurJe ne comprends pas cette tendance à vouloir tout mettre dans Postgres
Je suis heureux de voir davantage d’implémentations de recherche en texte intégral natives à Postgres
lucene/tantivy) sont conçues pour des segments immuables, donc combinées avec les tables heap de Postgres elles peuvent aboutir à une moins bonne solutionSans plan d’exécution, il est difficile de comprendre ce qui se passe
tsvectorne s’applique qu’aux correspondances, et comme la requête de benchmark est enLIMIT 10, il y a peu de revérificationsIl y a quelques années, je voulais utiliser le FTS natif, mais j’ai échoué
J’ai packagé les RPM/DEB des extensions
pg_searchetvchord_bm25J’ai vu beaucoup d’équipes passer directement à Elasticsearch ou Meilisearch
10 millions d’enregistrements, c’est un dataset jouet
J’ai utilisé pour la première fois le texte intégral de pg vers 2008