Als u willekeurige substringovereenkomsten wilt optimaliseren, is een optie om de pg_tgrm
module
. Voeg een index toe:
CREATE INDEX table_location_name_trigrams_key ON table
USING gin (location_name gin_trgm_ops);
Dit zal "Simple Cafe" opsplitsen in "sim", "imp", "mpl", enz., en een vermelding toevoegen aan de index voor elk trigam in elke rij. De queryplanner kan deze index dan automatisch gebruiken voor overeenkomsten met subtekenreekspatronen, waaronder:
SELECT * FROM table WHERE location_name ILIKE '%cafe%';
Deze zoekopdracht zoekt "caf" en "afe" op in de index, vindt de kruising, haalt die rijen op en controleert vervolgens elke rij tegen uw patroon. (Die laatste controle is nodig omdat het snijpunt van "caf" en "afe" overeenkomt met zowel "eenvoudig café" als "onveilige steiger", terwijl "%cafe%" slechts met één overeenkomt). De index wordt effectiever naarmate het invoerpatroon langer wordt, omdat het meer rijen kan uitsluiten, maar het is nog steeds niet zo efficiënt als het indexeren van hele woorden, dus verwacht geen prestatieverbetering ten opzichte van to_tsvector
.
Catch is, trigrammen werken helemaal niet voor patronen die minder dan drie tekens bevatten. Dat kan al dan niet een dealbreaker zijn voor uw toepassing.
Bewerken: Ik heb dit aanvankelijk als opmerking toegevoegd.
Ik had een andere gedachte gisteravond toen ik grotendeels sliep. Maak een cjk_chars
functie die een invoertekenreeks nodig heeft, regexp_matches
het volledige CJK Unicode-bereik en retourneert een array van dergelijke tekens of NULL
als geen. Voeg een GIN-index toe aan cjk_chars(location_name)
. Vraag dan naar:
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, unigrammen!