ФНС не поддерживает LIKE
Ранее принят ответ был неверным. Полнотекстовый поиск с его полнотекстовыми индексами вообще не для LIKE
оператора, он имеет свои операторы и не работает для произвольных строк. Он оперирует словами на основе словарей и корней. Это делает поддержку согласования префикса для слов , но не с LIKE
оператором:
Индексы триграмм для 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);
Пример запроса:
SELECT * FROM tbl WHERE col LIKE '%foo%'; -- leading wildcard
SELECT * FROM tbl WHERE col ILIKE '%foo%'; -- works case insensitively as well
Триграммы? А как насчет более коротких струн?
Слова с менее чем 3 буквами в индексированных значениях по-прежнему работают. Руководство:
При определении набора триграмм, содержащихся в строке, считается, что каждое слово имеет два префикса и один суффикс.
И поисковые шаблоны с менее чем 3 буквами? Руководство:
При LIKE
поиске как по регулярным выражениям, так и по регулярным выражениям имейте в виду, что шаблон без извлекаемых триграмм будет вырожден в сканирование полного индекса.
Это означает, что сканирование индекса / растрового индекса по-прежнему работает (планы запросов для подготовленного оператора не нарушаются), это просто не даст вам лучшей производительности. Как правило, нет больших потерь, поскольку одно- или двухбуквенные строки вряд ли являются избирательными (более нескольких процентов совпадений с базовой таблицей), а поддержка индекса не улучшит производительность с самого начала, потому что полное сканирование таблицы выполняется быстрее.
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:
pg_trgm
вам понадобится строка запроса длиной не менее 3 символов, напримерfo%
, не попадет в индекс, а вместо этого выполнит сканирование. Кое-что отметить.Возможно, самые быстрые - это привязанные шаблоны с чувствительностью к регистру, которые могут использовать индексы. т.е. в начале строки соответствия нет подстановочного знака, поэтому исполнитель может использовать сканирование диапазона индексов. ( соответствующий комментарий в документации находится здесь ) Lower и ilike также потеряют вашу способность использовать индекс, если вы специально не создадите индекс для этой цели (см. функциональные индексы ).
Если вы хотите найти строку в середине поля, вам следует изучить полнотекстовый или триграммный индексы . Первый из них находится в ядре Postgres, другой доступен в модулях contrib.
источник
Вы можете установить Wildspeed , другой тип индекса в PostgreSQL. Wildspeed работает с подстановочными знаками% word%, без проблем. Обратной стороной является размер индекса, он может быть большим, очень большим.
источник
Выполните указанный ниже запрос, чтобы повысить производительность запроса LIKE в postgresql. создайте такой индекс для больших таблиц:
источник
как бы то ни было, Django ORM имеет тенденцию использовать
UPPER(text)
для всехLIKE
запросов, чтобы сделать его нечувствительным к регистру,Добавление индекса
UPPER(column::text)
значительно ускорило мою систему, в отличие от всего остального.Что касается ведущего%, да, он не будет использовать индекс. См. Этот блог для отличного объяснения:
https://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning
источник
Недавно у меня была аналогичная проблема с таблицей, содержащей 200000 записей, и мне нужно выполнять повторяющиеся запросы LIKE. В моем случае искомая строка была исправлена. Остальные поля менялись. Благодаря этому я смог переписать:
так как
Я был рад, когда запросы вернулись быстро, и подтвердил, что индекс используется с
EXPLAIN ANALYZE
:источник
Ваши похожие запросы, вероятно, не могут использовать созданные вами индексы, потому что:
1) ваш критерий LIKE начинается с подстановочного знака.
2) вы использовали функцию с вашим критерием LIKE.
источник
Когда вы когда-либо используете предложение в столбце с функциями, например, LIKE, ILIKE, upper, lower и т. Д. Тогда postgres не будет принимать во внимание ваш обычный индекс. Он будет выполнять полное сканирование таблицы, просматривая каждую строку, и поэтому он будет медленным.
Правильный способ - создать новый индекс в соответствии с вашим запросом. Например, если я хочу сопоставить столбец без учета регистра, а мой столбец - varchar. Тогда вы можете сделать это вот так.
Точно так же, если ваш столбец представляет собой текст, вы делаете что-то вроде этого
Точно так же вы можете изменить верхнюю функцию на любую другую функцию, которую хотите.
источник