FTS не поддържа LIKE
По-рано приетият отговор беше неправилен. Пълнотекстово търсене с неговите пълни текстови индекси е не за LIKE
оператор изобщо, той има свои собствени оператори и не работи за произволни низове. Работи с думи въз основа на речници и изходни. Това прави поддържа съвпадение на префикс за думи , но не и с LIKE
оператор:
- Вземете частично съвпадение от GIN индексирана колона TSVECTOR
Индекси на триграма за LIKE
Инсталирайте допълнителния модул pg_trgm
който предоставя операторни класове за GIN и GiST триграмни индекси за поддръжка на всички LIKE
и ILIKE
шарките , а не само закотвени вляво:
Примерен индекс:
CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);
Или:
CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);
- Разлика между GiST и GIN индекс
Примерна заявка:
SELECT * FROM tbl WHERE col LIKE '%foo%'; -- leading wildcard
SELECT * FROM tbl WHERE col ILIKE '%foo%'; -- works case insensitively as well
Триграми? Ами по-късите струни?
Думи спо-малко от 3 букви в индексирани стойности все още работят. Ръководството:
При определяне на набора от триграми, съдържащи се в низа, всяка дума се счита, че има два интервала с префикс и един суфикс.
И модели за търсене с по-малко от 3 букви? Ръководството:
И за двете
LIKE
и търсения с регулярни изрази, имайте предвид, че модел без извличащи се триграми ще се изроди до сканиране с пълен индекс.
Това означава, че сканирането на индекс/растрова карта все още работи (плановете за заявка за подготвена декларация няма да се счупят), просто няма да ви осигури по-добра производителност. Обикновено няма голяма загуба, тъй като низовете от 1 или 2 букви не са селективни (повече от няколко процента от съвпаденията на основната таблица) и поддръжката на индекси не би подобрила производителността като начало, тъй като пълното сканиране на таблицата е по-бързо.
text_pattern_ops
за съвпадение на префикс
Само за ляво закотвен шаблони (без водещ заместващ знак) получавате оптимума с подходящ операторен клас за btree индекс:text_pattern_ops
или varchar_pattern_ops
. И двете вградени функции на стандартния Postgres, не е необходим допълнителен модул. Подобна производителност, но много по-малък индекс.
Примерен индекс:
CREATE INDEX tbl_col_text_pattern_ops_idx ON tbl(col text_pattern_ops);
Примерна заявка:
SELECT * FROM tbl WHERE col LIKE 'foo%'; -- no leading wildcard
Или , ако трябва да стартирате вашата база данни с 'C' локал (на практика не локал), тогава всичко така или иначе се сортира според реда на байтовете и обикновен индекс на btree с клас на оператор по подразбиране върши работата.
Повече подробности, обяснения, примери и връзки в тези свързани отговори на dba.SE:
- Съвпадение на образец с LIKE, SIMILAR TO или регулярни изрази в PostgreSQL
- Как е внедрен LIKE?
- Бързо намиране на подобни низове с PostgreSQL