PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Вариации в производителността на заявките в PostgreSQL LIKE

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Поправете „ГРЕШКА:  всяка UNION заявка трябва да има същия брой колони“ в PostgreSQL

  2. Може ли INSERT [...] ON CONFLICT да се използва за нарушения на външния ключ?

  3. Прозоречна функция на Postgres и групиране по изключение

  4. Оптимизирайте заявката с OFFSET върху голяма таблица

  5. Как да намерите името на ограничение в PostgreSQL