Pokud chcete optimalizovat libovolné shody podřetězců, jednou z možností je použít kód pg_tgrm
modul
. Přidat index:
CREATE INDEX table_location_name_trigrams_key ON table
USING gin (location_name gin_trgm_ops);
To rozdělí "Simple Cafe" na "sim", "imp", "mpl" atd. a přidá záznam do indexu pro každý trigam v každém řádku. Plánovač dotazů pak může tento index automaticky použít pro shody vzorů podřetězců, včetně:
SELECT * FROM table WHERE location_name ILIKE '%cafe%';
Tento dotaz vyhledá „caf“ a „afe“ v indexu, najde průsečík, načte tyto řádky a poté každý řádek porovná s vaším vzorem. (Tato poslední kontrola je nezbytná, protože průsečík "caf" a "afe" odpovídá jak "jednoduchá kavárna" tak "nebezpečné lešení", zatímco "%cafe%" by mělo odpovídat pouze jednomu). Index se stává efektivnější, když se vstupní vzor prodlužuje, protože může vyloučit více řádků, ale stále není tak účinný jako indexování celých slov, takže neočekávejte zlepšení výkonu oproti to_tsvector
.
Háček je v tom, že trigramy nefungují vůbec pro vzory, které mají méně než tři znaky. To může, ale nemusí být pro vaši aplikaci překážkou.
Upravit: Původně jsem to přidal jako komentář.
Včera v noci, když jsem většinou spal, mě napadla jiná myšlenka. Vytvořte cjk_chars
funkce, která přebírá vstupní řetězec, regexp_matches
celý rozsah CJK Unicode a vrátí pole jakýchkoli takových znaků nebo NULL
pokud žádný. Přidejte index GIN na cjk_chars(location_name)
. Poté dotaz na:
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, unigramy!