Postgresql - Index Access Method Interface Definition 索引访问方法接口定义(一)

我们来看一下官方文档介绍索引是如何工作的

PostgreSQL中的所有索引都是技术上称为辅助索引的索引,也就是说,索引与它所描述的表文件在物理上是分开的。每个索引存储为自己的物理relation,因此由pg_class目录中的条目来描述。索引的内容完全在其索引访问方法的控制之下。在实践中,所有索引访问方法将索引划分为标准大小页,以便它们可以使用常规存储管理器和缓冲区管理器访问索引内容。
索引实际上是从一些数据键值到索引父表中的行版本(元组)的元组标识符或TIDS的映射。TID由块内的块号和项目号组成。这是从表中获取特定行版本的充分信息。索引没有直接意识到在MVCC下,可能存在相同逻辑行的多个现存版本;对于索引,每个元组是需要自己索引项的独立对象。因此,即使键值没有改变,行的更新也总是为行创建新的索引条目。(热元组是这个语句的例外;但是索引也不处理这些。)当死元组本身被回收时,用死元组回收索引元组。

1. Basic API Structure for Indexes
Index的访问方法定义在pg_am。可以通过CREATE ACCESS METHOD 和 DROP ACCESS METHOD SQL创建删除条目。
mytest=# select * from pg_am;
amname | amhandler | amtype
--------+-------------+--------
btree | bthandler | i
hash | hashhandler | i
gist | gisthandler | i
gin | ginhandler | i
spgist | spghandler | i
brin | brinhandler | i
(6 rows)
索引访问方法处理程序函数以接受内部类型的单个参数,并返回伪类型的索引index_am_handler。该参数是一个哑值,它仅用于防止处理程序函数直接从SQL命令调用。函数的结果必须是类型IndexAmRoutine的palloc'd结构,它包含核心代码需要知道的所有使用索引访问方法的内容。IndexAmRoutine结构也称为Access方法的API结构,它包括指定访问方法的各种固定属性的字段,例如它是否可以支持多个索引。更重要的是,它包含指针来支持Access方法的函数,这些函数完成了访问索引的所有实际工作。这些支持函数是纯C函数,在SQL级别是不可见的或可调用的。
typedef struct IndexAmRoutine{ NodeTag type; /* * Total number of strategies (operators) by which we can traverse/search * this AM. Zero if AM does not have a fixed set of strategy assignments. */ uint16 amstrategies; /* total number of support functions that this AM uses */ uint16 amsupport; /* does AM support ORDER BY indexed column's value? */ bool amcanorder; /* does AM support ORDER BY result of an operator on indexed column? */ bool amcanorderbyop; /* does AM support backward scanning? */ bool amcanbackward; /* does AM support UNIQUE indexes? */ bool amcanunique; /* does AM support multi-column indexes? */ bool amcanmulticol; /* does AM require scans to have a constraint on the first index column? */ bool amoptionalkey; /* does AM handle ScalarArrayOpExpr quals? */ bool amsearcharray; /* does AM handle IS NULL/IS NOT NULL quals? */ bool amsearchnulls; /* can index storage data type differ from column data type? */ bool amstorage; /* can an index of this type be clustered on? */ bool amclusterable; /* does AM handle predicate locks? */ bool ampredlocks; /* does AM support parallel scan? */ bool amcanparallel; /* type of data stored in index, or InvalidOid if variable */ Oid amkeytype; /* interface functions */ ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; amcanreturn_function amcanreturn; /* can be NULL */ amcostestimate_function amcostestimate; amoptions_function amoptions; amproperty_function amproperty; /* can be NULL */ amvalidate_function amvalidate; ambeginscan_function ambeginscan; amrescan_function amrescan; amgettuple_function amgettuple; /* can be NULL */ amgetbitmap_function amgetbitmap; /* can be NULL */ amendscan_function amendscan; ammarkpos_function ammarkpos; /* can be NULL */ amrestrpos_function amrestrpos; /* can be NULL */ /* interface functions to support parallel index scans */ amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ aminitparallelscan_function aminitparallelscan; /* can be NULL */ amparallelrescan_function amparallelrescan; /* can be NULL */} IndexAmRoutine;
为了有用,索引访问方法还必须有一个或多个操作符族和操作符类,它们定义在pg_opfamily, pg_opclass, pg_amop, pg_amproc。这些条目允许palner确定哪些类型的查询资格可以与该访问方法的索引一起使用。
一个单独的索引由一个 pg_class条目定义,该条目将它描述为一个物理关系,再加上一个pg_index条目,它显示了索引的逻辑内容,即它所具有的索引列集合和这些列的语义,由相关的操作符类捕获。索引列(键值)可以是基础表的简单列,也可以是表行上的表达式。索引访问方法通常不关心索引键值来自何处(它总是传递预先计算的键值),但它对pg_index中的操作符类信息非常感兴趣。这些目录项都可以作为传递到索引上所有操作的关系数据结构的一部分来访问。
某些IndexAmRoutine的标志字段具有不明显的含义。amcanmulticol标志声明访问方法支持多个索引,amoptionalkey允许扫描第一索引列中没有可索引限制子句。当amcanmulticol为false时,amoptionalkey基本上表示访问方法是否支持没有任何限制子句的全索引扫描。支持多个索引列的访问方法必须支持省略第一个或所有列之后的限制的扫描;但是,它们允许对第一个索引列出现一些限制,并且通过设置amoptionalkey false来发出信号。索引AM可能设置amoptionalkey的一个原因是如果它不索引空值。由于大多数可转位运算符都是严格的,因此不能为空输入返回真值,因此,不为空值存储索引项是第一吸引力的:无论如何它们都不能被索引扫描返回。但是,当索引扫描对给定索引列没有限制子句时,此参数将失败。在实践中,这意味着具有amoptionalkey 为true 索引必须索引为空值,因为planer可能决定使用这样一个索引,而根本没有扫描键。相关的限制是,支持多个索引列的索引访问方法必须支持在第一个列之后的空值的索引,因为planer将假定索引可以用于不限制这些列的查询。例如,考虑一个索引(a,b)和一个带有a=4的查询。系统将假定索引可以用来扫描具有A=4的行,如果索引省略了B为null的行,则是错误的。但是,省略第一索引列为空的行是可以的。索引NULLS的索引访问方法也可以设置amsearchnulls,指示它支持IS NULL 和 IS NOT NULL子句作为搜索条件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值