54.1. 索引的目录项

每个索引访问方法都在系统目录pg_am中用一行来描述(见Section 47.3)。一个 pg_am行的主要内容是引用pg_proc中的项,它们标识索引访问方法提供的索引 访问函数。这些函数的 API 在本章稍后的部分中描述。另外,pg_am行指定了几个索引访问方法的固定属性,例如它是否 支持多列索引。目前还没有对创建或删除pg_am项提供特殊支持;任何能够编写一种新访问方法的人都需要能够为他们自己插入一个合适的行。

要想真正有用,一个索引访问方法还必须有一个或多个定义在pg_opfamilypg_opclasspg_amoppg_amproc中的操作符族操作符类。这些项允许规划器判断哪种查询条件适用于这个索引访问方法的索引。操作符族和类在Section 35.14中描述,它是阅读本章所需的前导材料。

一个独立的索引是由一个pg_class项定义的,该项描述索引为一个物理关系。还要加上一个pg_index项来显示索引的逻辑内容 — 也就是说,它所拥有的索引列集以及这些列的语义是被相关操作符类刻画的。索引列(键值)可以是底层表的 简单列,也可以是该表行上的表达式。索引访问方法通常不关心索引的键值来自那里(它总是操作预计算过的键值),但是它会对pg_index中的操作符类信息很感兴趣。所有这些目录项都可以被当作关系数据结构的一部分访问,这个数据结构会被传递给索引上的所有操作。

pg_am中的有些标志列的含义并不那么直观。amcanunique的要求在Section 54.5中讨论。amcanmulticol标志断言该索引访问方法支持多列索引, amoptionalkey断言它允许对那种在第一个索引列上没有给出可索引限制子句的扫描。如果amcanmulticol为假,那么amoptionalkey实际上说的是该访问方法是否允许不带限制子句的全索引扫描。 那些支持多索引列的访问方法必须支持那些在省略了除第一个列之外的任何或所有其它列上约束的扫描;不过,它们被允许去要求在第一个列上出现一些限制,并且这一点是以把amoptionalkey设置为假作为标志的。一个索引 AM 可能将amoptionalkey设置为假的一种原因是,如果它不索引空值。因为大多数可索引的操作符都是严格的并且因此不能对空输入返回真,所以不为空值存储索引项咋看上去很吸引人:因为它们不 可能被一个索引扫描返回。不过,当一个索引扫描对于一个给定索引列上没有约束子句时,这种讨论就不成立了。实际上,这意 味着设置了amoptionalkey为真的索引必须索引空值,因为规划器可能会决定在根本没有扫描键的时候使用这样的索引。一个相关的限制是一个支持 多索引列的索引访问方法必须支持索引第一列之后的列中的空值,因 为规划器会认为这个索引可以用于在那些列上没有限制的查询。例如,考虑一个在(a,b)上的索引和一个有WHERE a = 4的查询。系统会认为该索引可以用于扫描 a = 4的行, 如果索引忽略了 b 为空的行,那么就是错误的。不过,忽略那些在第一个索引列上值为空的行是 OK 的。一个索引空的索引访问方法可能也会设置amsearchnulls,表明它支持将IS NULLIS NOT NULL子句作为搜索条件。