- Die eingebaute Full-Text Search (FTS) von PostgreSQL gilt oft als langsam, kann mit der richtigen Optimierung jedoch sehr schnell arbeiten
- Im Blog von Neon wird die Rust-basierte Erweiterung
pg_search mit der eingebauten FTS verglichen und behauptet, letztere sei langsam
- Dieser Vergleich wurde jedoch wahrscheinlich in einem Zustand durchgeführt, in dem grundlegende, für PostgreSQL FTS essenzielle Optimierungen fehlten
- Dieser Beitrag belegt mit Zahlen, dass sich bereits mit einfachen Optimierungen der Standard-FTS eine 50-fache Leistungssteigerung erzielen lässt
Überblick über das Benchmark-Setup
- Getestet wurde auf Basis einer Tabelle mit 10 Millionen Log-Datensätzen
CREATE TABLE benchmark_logs (
id SERIAL PRIMARY KEY,
message TEXT,
country VARCHAR(255),
severity INTEGER,
timestamp TIMESTAMP,
metadata JSONB
);
- Die problematische Query-Struktur:
SELECT country, COUNT(*)
FROM benchmark_logs
WHERE to_tsvector('english', message) @@ to_tsquery('english', 'research')
GROUP BY country
ORDER BY country;
to_tsvector() wird innerhalb der Query ausgeführt → sehr ineffizient
- Selbst mit GIN-Index wird dieser nicht richtig genutzt
Testumgebung (Nachbildung der Standardeinstellungen)
Leistungsproblem 1: tsvector-Berechnung zur Laufzeit
Leistungsproblem 2: GIN-Index mit fastupdate=on
Leistungsgewinn: mehr als 50-fache Verbesserung
- Vor der Optimierung: ca. 41,3 Sekunden (41.301 ms)
- Nach der Optimierung: ca. 0,88 Sekunden (877 ms)
- Das entspricht einer rund 50-fachen Leistungssteigerung
- Diese Performance ist auch in Umgebungen mit wenig Parallelverarbeitung erreichbar
Die Performance von ts_rank kann tatsächlich langsam sein
ts_rank oder ts_rank_cd bewerten alle Ergebnisse und sortieren sie anschließend, weshalb sie relativ langsam sein können
- Besonders bei großen Ergebnismengen ist die CPU-/IO-Last hoch
Erweiterte Ranking-Funktion: Erweiterung VectorChord-BM25
- Wenn Sortiergenauigkeit und Geschwindigkeit wichtig sind, ist eine spezialisierte Erweiterung oft effektiver
- VectorChord-BM25 ist eine PostgreSQL-Erweiterung, die Ranking auf Basis des BM25-Algorithmus bietet
- Berichten zufolge ist sie 3-mal schneller als Elasticsearch
Vorteile von VectorChord-BM25
- BM25-Algorithmus: ein weiterentwickelter Suchranking-Algorithmus gegenüber TF-IDF
- Spezielles Indexformat: für schnelle Suche optimiert, etwa mit Block WeakAnd
- Bietet den Typ
bm25vector: speichert tokenisierte Repräsentationen
- Verbessert sowohl Suchgenauigkeit als auch Geschwindigkeit
Fazit: Auch die Standard-FTS von PostgreSQL ist schnell genug
- Mit einer
tsvector-Spalte und einem passenden GIN-Index (fastupdate=off) sind auch mit der eingebauten FTS sehr schnelle Suchen möglich
- Leistungsvergleiche sollten auf optimierten Grundlagen erfolgen
- Wenn erweiterte Ranking-Funktionen nötig sind, lohnt sich der Einsatz von Erweiterungen wie VectorChord-BM25
- Die Kernbotschaft: Nicht das Tool ist langsam, sondern möglicherweise die Konfiguration
3 Kommentare
Dadurch habe ich das Query-Tuning durchgeführt.
Die Meinungen auf Hacker News sind ja furchteinflößend ... „Zehn Millionen? Ein Witz?“
Hacker-News-Kommentare
Als Maintainer von pg_search gilt laut der Postgres-Dokumentation sowohl der Neon/ParadeDB-Artikel als auch die hier verwendete Strategie als valide Alternative
tsvectorin Echtzeit zu berechnen, ist ein großer FehlerIch verstehe den Drang nicht, alles in Postgres zu packen
Ich freue mich, mehr Postgres-native Implementierungen für Volltextsuche zu sehen
Ohne Explain-Plan ist schwer zu verstehen, was passiert
tsvectorin Echtzeit nur auf Treffer angewendet, und da die Benchmark-QueryLIMIT 10verwendet, gibt es nur wenige RechecksVor ein paar Jahren wollte ich native FTS verwenden, bin aber gescheitert
Ich habe RPM/DEB-Pakete für die Erweiterungen pg_search und vchord_bm25 gebaut
Ich habe viele Teams direkt zu Elasticsearch oder Meilisearch wechseln sehen
10 Millionen Datensätze sind ein Spielzeug-Datensatz
Ich habe pg Volltextsuche um 2008 herum zum ersten Mal verwendet