Обобщенные типы индексов PostgreSQL
263
Конечно,
атрибуты, включаемые в индекс GiST, не обязательно должны
быть координатами. Такие атрибуты могут представлять время или другие
упорядоченные типы данных.
Индексы для полнотекстового поиска
PostgreSQL предоставляет два типа индексов, которые поддерживают текс-
товый поиск. Начнем с обсуждения индексов GIN, что означает Generalized
Inverted Index – обобщенный инвертированный индекс.
В целях индексации документ рассматривается как список термов (или фраг-
ментов) и представляется значением типа данных
tsvector
, описанного ранее.
Для
каждого терма, содержащегося хотя бы в одном документе, инвер-
тированный индекс содержит список документов, содержащих этот терм.
Таким образом, общая структура симметрична: у
документа есть список
термов, а у терма есть список документов. Эта симметрия объясняет, почему
тип индекса называется инвертированным.
Инвертированные индексы могут эффективно поддерживать текстовый
поиск. Например, чтобы найти документы, содержащие все термы, указан-
ные в запросе, PostgreSQL сканирует все списки документов этих термов
и оставляет только те документы, которые присутствуют в каждом из спис-
ков.
Списки упорядочены, поэтому для получения набора результатов до-
статочно одного прохода по спискам.
Индекс GIN может быть создан как функциональный индекс с выражени-
ем, преобразующим индексируемый документ в
tsvector
, или же значения
tsvector
могут храниться как отдельный столбец. Преимущество первого
подхода состоит в экономии места, а преимущество последнего в том, что
индекс не зависит от конфигурации (поскольку конфигурация нужна только
для вычисления значения
tsvector
).
Если значения
tsvector
сохраняются,
то можно индексировать документы, написанные на разных естественных
языках и преобразованные в
tsvector
разными конфигурациями.
Структура GIN не является производной от естественного языка и никак не
связана с ним; как отмечалось ранее, документы считаются списками. Таким
образом, индекс может работать с данными, отличными от документов, –
фактически
с любым типом атрибута, содержащим несколько элементов,
например с массивами. Индекс GIN будет находить строки с атрибутами, со-
держащими все элементы, указанные в запросе, точно так же как он находит
все документы, содержащие указанные термы.
Документы (значения типа
tsvector
) также можно индексировать с по-
мощью индекса GiST. Чтобы создать такой индекс, значения
tsvector
преоб-
разуются в битовые карты фиксированной длины, построенные следующим
образом. Каждому терму, который появляется в любом из индексируемых
документов, соответствует позиция в битовой карте, которая определяется
значением хеш-функции, вычисленной для этого терма. Каждый терм пред-
ставляется битовой картой той же длины, в которой установлен в единицу
единственный бит в вычисленной позиции; все остальные биты равны нулю.
Битовая карта документа – это побитовое логическое «или» всех битовых
264
Более
сложная фильтрация и поиск
карт, которые представляют термы документв. Таким образом, в битовой
карте документа установлены в единицу все биты, соответствующие термам,
которые присутствуют в этом документе. Битовая карта запроса строится
аналогичным образом.
Поиск по такому индексу основан на том, что документ удовлетворяет за-
просу, если его битовая карта содержит единицу в каждой позиции, в которой
единица содержится в битовой карте запроса.
Хеш-функция может поместить различные термы в одну и ту же позицию.
Поэтому индекс GiST может возвращать документы, не относящиеся к за-
просу, и обычно требуется перепроверка значений
tsvector
, но PostgreSQL
выполняет ее автоматически.
Количество ложных совпадений увеличивается с ростом количества раз-
личных термов. Следовательно, индекс GiST эффективен для коллекций до-
кументов, в которых общее количество различных термов невелико. Для тек-
стов, написанных на естественных языках, это, как правило, не так, поэтому
индексы GIN обычно более эффективны. Но в некоторых случаях индексы
GiST для текстового поиска могут оказаться полезными.
Do'stlaringiz bilan baham: