Существует два типа индексов, которые могут применяться для ускорения полнотекстового поиска: GIN и GiST. Следует отметить, что использование индексов не является обязательным для полнотекстового поиска, однако в случаях, когда поиск по столбцу выполняется регулярно, создание индекса обычно является целесообразным.
Для создания такого индекса выполните одно из следующих действий:
CREATE INDEX имя ON таблица USING GIN (столбец);
Создает индекс на основе GIN (Generalized Inverted Index — обобщенного инвертированного индекса).
Данный столбец должен иметь tsvector тип.
CREATE INDEX имя ON таблица USING GIST (столбец [ { DEFAULT | tsvector_ops } (siglen = число) ] );
Создает индекс на основе GiST (Generalized Search Tree — обобщенного дерева поиска).
Данный столбец может иметь tsvector или
tsquery тип.
Необязательный целочисленный параметр siglen определяет
длина сигнатуры в байтах (подробности приведены ниже).
Индексы GIN являются предпочтительным типом индекса для текстового поиска. Являясь инвертированными индексами, они содержат индексную запись для каждого слова (лексемы) со сжатым списком соответствующих позиций. Поиск по нескольким словам позволяет найти
первое совпадение, а затем использовать индекс для исключения строк, в которых отсутствуют
дополнительные слова. В индексах GIN хранятся только слова (лексемы)
tsvector значений, а не их весовые метки. Таким образом, при выполнении запроса, учитывающего веса, требуется повторная проверка строки таблицы.
Индекс GiST является lossy, что означает, что индекс
может возвращать ложные совпадения, и для их исключения необходимо
обращаться к фактической строке таблицы.
(Digital Q.DataBase выполняет это автоматически по мере необходимости.)
Индексы GiST характеризуются потерей точности, так как каждый документ представлен в
индексе сигнатурой фиксированной длины. Длина сигнатуры в байтах определяется
значением необязательного целочисленного параметра siglen.
Длина сигнатуры по умолчанию (если siglen параметр не указан) составляет 124 байта, а максимальная длина сигнатуры — 2024 байта. Сигнатура генерируется путем хеширования каждого слова в один бит n-битной строки с последующим объединением этих битов по правилу логического «ИЛИ» для формирования n-битной сигнатуры документа. В случае хеширования двух слов в одну и ту же битовую позицию возникает ложное срабатывание. Если для всех слов в запросе найдены совпадения (истинные или ложные), необходимо извлечь строку таблицы для проверки корректности соответствия. Более длинные сигнатуры обеспечивают более высокую точность поиска (сканирование меньшей части индекса и меньшего количества страниц кучи) при одновременном увеличении размера самого индекса.
Индекс GiST может быть покрывающим, то есть использовать INCLUDE
предложение. Включенные столбцы могут иметь типы данных, для которых отсутствуют какие-либо классы операторов GiST. Включенные атрибуты сохраняются в несжатом виде.
Потеря точности (lossiness) приводит к снижению производительности из-за избыточных чтений записей таблицы, которые в итоге оказываются ложными срабатываниями. Поскольку произвольный доступ к записям таблицы осуществляется медленно, это ограничивает эффективность использования индексов GiST. Вероятность ложных срабатываний зависит от нескольких факторов, в частности от количества уникальных слов, поэтому для сокращения этого числа рекомендуется использовать словари.
Обратите внимание, что GIN время построения индекса часто может быть сокращено путем увеличения значения maintenance_work_mem, в то время как GiST время построения индекса не чувствительно к данному параметру.
Секционирование больших коллекций и надлежащее использование индексов GIN и GiST позволяют реализовать механизмы высокоскоростного поиска с возможностью оперативного обновления. Секционирование может быть выполнено на уровне базы данных с использованием механизма наследования таблиц или путем распределения документов по серверам и последующего сбора результатов внешнего поиска, например, через механизмы доступа к сторонним данным (Foreign Data Access). Последнее становится возможным, так как функции ранжирования используют только локальную информацию.