12.9. Предпочтительные типы индексов для текстового поиска#
12.9. Предпочтительные типы индексов для текстового поиска
Существует два вида индексов, которые могут использоваться для ускорения полнотекстового поиска: GIN и GiST. Обратите внимание, что индексы не являются обязательными для полнотекстового поиска, но в случаях, когда столбец часто используется для поиска, индекс обычно желателен.
Для создания такого индекса выполните одно из следующих действий:
-
CREATE INDEX
name
ONtable
USING GIN (column
); Создает индекс на основе GIN (Generalized Inverted Index). Столбец
column
должен иметь типtsvector
.-
CREATE INDEX
name
ONtable
USING GIST (column
[ { DEFAULT | tsvector_ops } (siglen =number
) ] ); Создает индекс на основе GiST (Generalized Search Tree).
column
может быть типаtsvector
илиtsquery
. Необязательный целочисленный параметрsiglen
определяет длину сигнатуры в байтах (см. ниже для получения более подробной информации).
GIN индексы являются предпочтительным типом индекса полнотекстового поиска. Как инвертированные индексы, они содержат запись индекса для каждого слова (лексемы) с сжатым списком совпадающих местоположений. Поиск по нескольким словам может найти первое совпадение, а затем использовать индекс для удаления строк, которым не хватает дополнительных слов. GIN индексы хранят только слова (лексемы) значений tsvector
, а не их весовые метки. Таким образом, требуется повторная проверка строки таблицы при использовании запроса, который включает веса.
Индекс GiST является потерянным, что означает, что индекс может давать ложные совпадения, и необходимо проверять фактическую строку таблицы, чтобы исключить такие ложные совпадения. (Tantor SE делает это автоматически при необходимости). Индексы GiST являются потерянными, потому что каждый документ представлен в индексе фиксированной длиной подписи. Длина подписи в байтах определяется значением необязательного целочисленного параметра siglen
. По умолчанию длина подписи (когда siglen
не указан) составляет 124 байта, максимальная длина подписи составляет 2024 байта. Подпись генерируется путем хеширования каждого слова в один бит в строке из n бит, с помощью операции ИЛИ всех этих битов для получения подписи документа из n битов. Когда два слова хешируются в одну и ту же позицию бита, возникает ложное совпадение. Если все слова в запросе имеют совпадения (реальные или ложные), то строка таблицы должна быть извлечена, чтобы увидеть, является ли совпадение правильным. Более длинные подписи обеспечивают более точный поиск (сканирование меньшей доли индекса и меньшее количество страниц кучи), но требуют большего объема индекса.
Индекс GiST может быть покрывающим, т.е. использовать предложение INCLUDE
. Включенные столбцы могут иметь типы данных без какого-либо оператора GiST
класс. Включенные атрибуты будут храниться в несжатом виде.
Потеря данных приводит к снижению производительности из-за ненужных выборок записей таблицы, которые оказываются ложными совпадениями. Поскольку случайный доступ к записям таблицы медленный, это ограничивает полезность индексов GiST. Вероятность ложных совпадений зависит от нескольких факторов, в частности от количества уникальных слов, поэтому рекомендуется использовать словари для сокращения этого числа.
Обратите внимание, что время создания индекса GIN часто можно улучшить, увеличив maintenance_work_mem, в то время как время создания индекса GiST не зависит от этого параметра.
Разделение больших коллекций и правильное использование индексов GIN и GiST позволяют реализовать очень быстрые поиски с онлайн-обновлением. Разделение может быть выполнено на уровне базы данных с использованием наследования таблиц, или путем распределения документов по серверам и сбора внешних результатов поиска, например, через доступ к внешним данным (Foreign Data). Последнее возможно, потому что функции ранжирования используют только локальную информацию.