Ако искате да оптимизирате произволни съвпадения на подниз, една от опциите е да използвате кода>pg_tgrm модул . Добавяне на индекс:
CREATE INDEX table_location_name_trigrams_key ON table
USING gin (location_name gin_trgm_ops);
Това ще раздели "Simple Cafe" на "sim", "imp", "mpl" и т.н. и ще добави запис към индекса за всяка тригама във всеки ред. След това програмата за планиране на заявки може автоматично да използва този индекс за съвпадения на модел на подниз, включително:
SELECT * FROM table WHERE location_name ILIKE '%cafe%';
Тази заявка ще търси "caf" и "afe" в индекса, ще намери пресечната точка, ще извлече тези редове, след което ще провери всеки ред спрямо вашия модел. (Тази последна проверка е необходима, тъй като пресечната точка на "caf" и "afe" съвпада както с "simple cafe", така и с "unsafe scaffolding", докато "%cafe%" трябва да съвпада само с едно). Индексът става по-ефективен, когато шаблонът за въвеждане става по-дълъг, тъй като може да изключи повече редове, но все още не е толкова ефективен, колкото индексирането на цели думи, така че не очаквайте подобрение на производителността спрямо to_tsvector
.
Уловката е, че триграмите изобщо не работят за модели под три знака. Това може или не може да бъде проблем за вашето приложение.
Редактиране: Първоначално добавих това като коментар.
Имах друга мисъл снощи, когато почти спях. Направете cjk_chars
функция, която приема входен низ, regexp_matches
целия диапазон на CJK Unicode и връща масив от всякакви такива знаци или NULL
ако няма. Добавете GIN индекс към cjk_chars(location_name)
. След това потърсете:
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
Та-да, униграми!