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



Я видел довольно большое изменение времени отклика относительно LIKE запросы к определенной таблице в базе данных. Иногда я получаю результаты в течение 200-400 мс (очень приемлемо), но в других случаях это может занять до 30 секунд, чтобы вернуть результаты.



Я понимаю, что LIKE запросы очень ресурсоемкие, но я просто не понимаю, почему будет такая большая разница во времени отклика. Я построил индекс btree на

675   6  

6 ответов:

FTS не поддерживает LIKE

The ранее принятый ответ был неверным. Полнотекстовый Поиск С его полнотекстовыми индексами это не на LIKE оператор вообще, он имеет свои собственные операторы и не работает для произвольных строк. Он работает на слова на основе словарей и вытекающие. Это тут поддержка префикс соответствия для слов, а не LIKE оператор:

индексы триграмм для LIKE

установите дополнительный модуль pg_trgm, который предоставляет классы для оператора джин и Гист триграммы индексы в поддержку все 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 и регулярные выражения поиска, имейте в виду, что a шаблон без извлекаемых триграмм вырождается в полноиндексное сканирование.

это означает, что сканирование индекса / растрового индекса все еще работает (планы запросов для подготовленного оператора не будут ломаться), он просто не купит вас лучше спектакль. Как правило, нет больших потерь, так как 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' locale (эффективно нет locale), то все сортируется в соответствии с порядком байтов в любом случае и простой индекс btree по умолчанию класс оператора выполняет эту работу.

более подробная информация, объяснение, примеры и ссылки в этих связанных ответах на dba.SE:

возможно, быстрые из них привязаны шаблоны с учетом регистра, как это может использовать индексы. т. е. в начале строки соответствия нет подстановочного знака, поэтому исполнитель может использовать сканирование диапазона индексов. (соответствующий комментарий в документах находится здесь) Lower и ilike также потеряют вашу способность использовать индекс, Если вы специально не создадите индекс для этой цели (см. функциональные показатели).

Если вы хотите найти строку в середине поле, вы должны смотреть в полный текст или триграмма индексы. Первый из них находится в ядре Postgres, другой доступен в модулях contrib.

вы можете установить Wildspeed другой тип индекса в PostgreSQL. Wildspeed работает с% word % wildcards, без проблем. Недостатком является размер индекса, это может быть большой, очень большой.

пожалуйста, выполните указанный ниже запрос для улучшения производительности подобных запросов в postgresql. создать такой индекс для больших таблиц:

CREATE INDEX <indexname> ON <tablename> USING btree (<fieldname> text_pattern_ops)

ваши подобные запросы, вероятно, не могут использовать созданные вами индексы, потому что:

1) Ваши подобные критерии начинаются с подстановочного знака.

2) вы использовали функцию с критериями.

чего бы это ни стоило,Джанго ORM имеет тенденцию использовать UPPER(text) для всех LIKE запросов, чтобы сделать его нечувствительным к регистру,

добавление индекса на UPPER(column::text) значительно ускорило мою систему, в отличие от любой другой вещи.

что касается ведущего %, Да, что не будет использовать индекс. Смотрите этот блог для отличного объяснения:

https://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning

Comments

    Ничего не найдено.