Om du vill optimera godtyckliga delsträngsmatchningar är ett alternativ att använda
CREATE INDEX table_location_name_trigrams_key ON table
USING gin (location_name gin_trgm_ops);
Detta kommer att dela upp "Simple Cafe" i "sim", "imp", "mpl", etc., och lägga till en post till indexet för varje trigam i varje rad. Frågeplaneraren kan sedan automatiskt använda detta index för delsträngsmönstermatchningar, inklusive:
SELECT * FROM table WHERE location_name ILIKE '%cafe%';
Den här frågan kommer att slå upp "caf" och "afe" i indexet, hitta korsningen, hämta dessa rader och sedan kontrollera varje rad mot ditt mönster. (Den sista kontrollen är nödvändig eftersom skärningspunkten mellan "caf" och "afe" matchar både "enkelt café" och "osäkra byggnadsställningar", medan "%cafe%" bara ska matcha en). Indexet blir mer effektivt när inmatningsmönstret blir längre eftersom det kan utesluta fler rader, men det är fortfarande inte lika effektivt som att indexera hela ord, så förvänta dig inte en prestandaförbättring jämfört med to_tsvector
.
Haken är att trigram inte fungerar alls för mönster som under tre tecken. Det kan eller kanske inte är en deal-breaker för din ansökan.
Redigera: Jag lade först till detta som en kommentar.
Jag fick en annan tanke igår kväll när jag mest sov. Gör en cjk_chars
funktion som tar en indatasträng, regexp_matches
hela CJK Unicode-intervallen och returnerar en array av sådana tecken eller NULL
om ingen. Lägg till ett GIN-index på cjk_chars(location_name)
. Fråga sedan efter:
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, unigram!