Wenn Sie willkürliche Teilstring-Übereinstimmungen optimieren möchten, besteht eine Möglichkeit darin, den pg_tgrm
Modul
. Index hinzufügen:
CREATE INDEX table_location_name_trigrams_key ON table
USING gin (location_name gin_trgm_ops);
Dadurch wird "Simple Cafe" in "sim", "imp", "mpl" usw. aufgeteilt und dem Index für jedes Trigam in jeder Zeile ein Eintrag hinzugefügt. Der Abfrageplaner kann diesen Index dann automatisch für Musterübereinstimmungen von Teilzeichenfolgen verwenden, einschließlich:
SELECT * FROM table WHERE location_name ILIKE '%cafe%';
Diese Abfrage wird im Index nach „caf“ und „afe“ suchen, die Schnittmenge finden, diese Zeilen abrufen und dann jede Zeile mit Ihrem Muster vergleichen. (Diese letzte Überprüfung ist notwendig, da die Schnittmenge von „caf“ und „afe“ sowohl mit „simple cafe“ als auch mit „unsafe scaffolding“ übereinstimmt, während „%cafe%“ nur mit einem übereinstimmen sollte). Der Index wird effektiver, wenn das Eingabemuster länger wird, da er mehr Zeilen ausschließen kann, aber er ist immer noch nicht so effizient wie das Indizieren ganzer Wörter, erwarten Sie also keine Leistungsverbesserung gegenüber to_tsvector
.
Der Haken an der Sache ist, dass Trigramme überhaupt nicht für Muster mit weniger als drei Zeichen funktionieren. Das kann ein Deal-Breaker für Ihre Bewerbung sein oder auch nicht.
Bearbeiten: Ich habe dies ursprünglich als Kommentar hinzugefügt.
Ich hatte letzte Nacht einen anderen Gedanken, als ich meistens schlief. Erstellen Sie ein cjk_chars
Funktion, die eine Eingabezeichenfolge akzeptiert, regexp_matches
den gesamten CJK-Unicode-Bereich und gibt ein Array solcher Zeichen oder NULL
zurück wenn keine. Fügen Sie einen GIN-Index zu cjk_chars(location_name)
hinzu . Dann fragen Sie nach:
WHERE CASE
WHEN cjk_chars('query') IS NOT NULL THEN
cjk_chars(location_name) @> cjk_chars('query')
AND location_name LIKE '%query%'
ELSE
<tsvector/trigrams>
END
Ta-da, Unigramme!