55.1. Записи каталога для индексов

Каждый метод доступа индекса описывается строкой в системном каталоге pg_am (см. Раздел 48.3). Первостепенными полями строки pg_am являются ссылки на записи в pg_proc, описывающие функции доступа к индексу, предоставляемые данным методом доступа. Программный интерфейс этих функций описывается в этой главе далее. Кроме того, в строке в pg_am задаётся набор фиксированных свойств метода доступа, например отмечается, поддерживает ли он многоколоночные индексы. В настоящее время нет никаких специальных средств для создания или удаления записей из pg_am; предполагается, что те, кто способны реализовать новый метод доступа, смогут и вставить соответствующую строку.

Чтобы метод доступа индекса применялся, необходимо также определить семейства операторов и классы операторов в pg_opfamily, pg_opclass, pg_amop и pg_amproc. Эти записи позволяют планировщику понять, для каких видов условий запросов могут применяться индексы с данными методом доступа. Семейства и классы операторов описываются в Разделе 35.14; этот материал необходимо изучить, прежде чем читать данную главу.

Отдельный индекс определяется записью в pg_class, описывающей его как физическое отношение, и записью в pg_index, представляющей логическое содержание индекса — то есть, набор колонок индекса и семантическое значение этих колонок, установленное соответствующими классами операторов. Колонками индекса (значениями ключа) могут быть либо простые колонки нижележащей таблицы, либо выражения, вычисляемые по строкам таблицы. Для метода доступа индекса обычно не важно, откуда поступают значения ключа индекса (они всегда поступают в вычисленном виде), но очень важна информация о классе операторов в каталоге pg_index. Обе эти записи каталогов представлены в составе структуры данных Relation, которая передаётся всем функциям, реализующим операции с индексом.

С некоторыми колонками флагов в pg_am связаны неочевидные следствия. Требования индексов с amcanunique описаны в Разделе 55.5. Флаг amcanmulticol показывает, что метод доступа поддерживает многоколоночные индексы, а amoptionalkey обозначает, что метод позволяет выполнить сканирование при отсутствии индексируемого ограничивающего условия для первой колонки индекса. Когда amcanmulticol равен false, amoptionalkey по сути говорит, поддерживает ли метод доступа полное сканирование по индексу без ограничивающего условия. Методы доступа, поддерживающие индексы по нескольким колонкам, должны поддерживать сканирования при отсутствии ограничений любых или всех колонок после первой; однако они могут требовать присутствия какого-либо ограничения для первой колонки индекса, и это требование отмечается значением false флага amoptionalkey. В amoptionalkey для метода доступа может устанавливаться false, например, когда этот метод доступа не индексирует значения NULL. Так как большинство индексируемых операторов — строгие, и поэтому не могут вернуть true для операндов NULL, на первый взгляд кажется заманчивой идея не хранить записи индекса для значений NULL: они всё равно никак не могут быть прочитаны при сканировании индекса. Однако, этот аргумент отпадает, когда при сканировании индекса вовсе отсутствует ограничение данной колонки индекса. На практике это означает, что индексы с установленным флагом amoptionalkey должны индексировать значения NULL, так как планировщик может склониться к использованию этого индекса вообще без ключей. С этим связано ещё одно ограничение — метод доступа индекса, поддерживающий многоколоночные индексы, должен поддерживать индексирование значений NULL в колонках после первой, так как планировщик будет полагать, что индекс можно применять для запросов, в которых эти колонки не ограничиваются. Например, рассмотрим индекс по (a,b) и запрос с ограничением WHERE a = 4. Система будет полагать, что по этому индексу можно просканировать строки с a = 4, но это будет неверно, если индекс исключит строки, в которых b равно NULL. Однако, этот индекс вполне может исключить строки, в которых первая колонка содержит NULL. Метод индекса, который индексирует значения NULL, может также установить флаг amsearchnulls, отметив тем самым, что он поддерживает в качестве условий поиска IS NULL и IS NOT NULL.