тиПы
индексов
P
ostgre
sQL
Оператор
CREATE
INDEX
позволяет при создании индекса указать его тип. Ни
в одном из предыдущих примеров это не было показано, потому что все ра-
нее созданные индексы были B-деревьями, а именно B-дерево используется
по умолчанию в качестве типа индекса. Другими возможными значениями
типа на момент написания этой главы были
hash
,
gist
,
spgist
,
gin
и
brin
.
В данном разделе более подробно рассматриваются некоторые из этих
типов.
Индексы GiST
Некоторые приложения используют объекты с несколькими атрибутами, на-
пример точки на поверхности или на плоскости. Ранее мы обсуждали состав-
ные индексы, включающие несколько атрибутов. Однако составные индексы
не симметричны: атрибуты в них упорядочены. Напротив, координаты точки
следует считать симметричными.
Для таких приложений подойдет тип индекса GiST, который индексирует
точки. Условия поиска выражаются прямоугольником: возвращаются все
точки, находящиеся внутри этого прямоугольника.
Если говорить точнее, GiST – это семейство индексных структур, каждая из
которых поддерживает определенный тип данных. В дистрибутив PostgreSQL
включена поддержка точек; некоторые другие типы данных могут быть уста-
новлены как расширения.
Обобщенные типы индексов 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: |