Jeśli chcesz zoptymalizować dowolne dopasowania podciągów, jedną z opcji jest użycie pg_tgrm
moduł
. Dodaj indeks:
CREATE INDEX table_location_name_trigrams_key ON table
USING gin (location_name gin_trgm_ops);
Spowoduje to podział „Simple Cafe” na „sim”, „imp”, „mpl” itp. oraz dodanie wpisu do indeksu dla każdego trygamu w każdym wierszu. Planer zapytań może następnie automatycznie użyć tego indeksu do dopasowania wzorców podłańcuchów, w tym:
SELECT * FROM table WHERE location_name ILIKE '%cafe%';
To zapytanie wyszuka w indeksie ciągi „caf” i „afe”, znajdzie przecięcie, pobierze te wiersze, a następnie porówna każdy wiersz z wzorcem. (To ostatnie sprawdzenie jest konieczne, ponieważ przecięcie „caf” i „afe” pasuje zarówno do „prostej kawiarni”, jak i „niebezpiecznego rusztowania”, podczas gdy „%cafe%” powinno odpowiadać tylko jednemu). Indeks staje się bardziej efektywny, gdy wzorzec wejściowy staje się dłuższy, ponieważ może wykluczyć więcej wierszy, ale nadal nie jest tak wydajny jak indeksowanie całych słów, więc nie oczekuj poprawy wydajności w porównaniu z to_tsvector
.
Złapanie jest takie, że trygramy w ogóle nie działają dla wzorców poniżej trzech znaków. To może, ale nie musi, być przełomem dla Twojej aplikacji.
Edytuj: Początkowo dodałem to jako komentarz.
Wczoraj wieczorem miałem inną myśl, kiedy prawie spałem. Zrób cjk_chars
funkcja, która pobiera ciąg wejściowy, regexp_matches
całe zakresy Unicode CJK i zwraca tablicę takich znaków lub NULL
jeśli nie. Dodaj indeks GIN do cjk_chars(location_name)
. Następnie zapytaj o:
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!