您的位置:首页 > 其它

PG索引特色

2019-05-27 10:31 10 查看

索引特色

表达式上的索引

PG支持函数索引,PG索引的键,除了可以是一个函数外,还可以是从一个或多个字段计算出来的标量表达式

在做大小写无关比较时,常用方法是使用lower函数,但因为用了函数,无法利用到“note”字段上的普通索引,所以此时需要建一个函数索引

表达式上的索引并不是在进行索引查找时计算表达式的,而是在插入数据行或更新数据行时进行计算的,因此在插入或更新时,表达式上的索引会慢一些

在表达式上的索引可以实现简单唯一约束无法实现的一些约束

 

部分索引

部分索引是只对一个表中的部分行进行的索引,由一个条件表达式把这部分行筛选出来,这个条件表达式被称为部分索引的谓词。部分索引在一些情况下非常有用,官方手册上给出了三个示例

一、设置一个部分索引以排除普通数值

二、设置一个部分索引以排除不感兴趣的数值

PG支持带任意谓词的部分索引,只要涉及被索引的表的字段就可以。不过谓词必须和那些希望从该索引中获益的查询中的where条件相匹配。准确的说只有在系统识别出该查询的where条件简单地包含了该索引的谓词时,此部分索引才能用于该查询。PG还不可以完全识别形式不同但数学上相等的谓词,但可以识别简单的不相等的包含,谓词条件必须准确匹配查询的where条件,不然系统将无法识别该索引是否可用

条件匹配发生在执行计划的规划期间而不是运行期间,因此带绑定变量的条件不能使用部分索引

三、设置一个部分唯一索引

部分索引的第三种用途是在表的子集里创建唯一索引,这样就可强制在满足谓词的行中保持唯一性,同时并不约束那些不需要唯一的行

 

GiST索引

GiST---Generalized Search Tree的缩写,通用搜索树,是一种平衡树结构的访问方法,是用户建立自定义索引的一个基础模板,用户只要按模板实现所要求的GiST操作类中的一系列回调函数,就可以实现自定义的索引,不用去关系这个GiST索引具体是如何存储的。B-tree和许多其他的索引都可以用GiST实现

实现新的索引访问意味大量非常有难度的开发工作,要理解PG内部工作机制、锁机制和WAL日志等,GiST实现了高级的编程接口,只要求实现者实现被访问的数据类型的一些回调函数,GiST框架层本身将会处理并发、WAL日志和搜索树结构处理的任务,大大降低了开发一种新索引访问方式的难度

PG支持在任意数据类型上建立B-tree索引,但B-tree只支持范围谓词(<,=,>),hash索引仅支持相等查询,而GiST的索引还能支持包含(@>)、重叠(&&)等复杂运算

要实现一个自定义的GiST索引操作类,需要实现GiST索引操作类的以下7个用户自定义函数:

*consistent:给出一个索引项p和一个查询q,这个函数确定索引项是否与查询相容(consitent),也就是说,条件"indexed_column indexable_operator q”对于此索引项下的所有行是否为真?这主要是为了测试是否需要扫描此索引节点下的子节点,如果返回为真,会返回一个recheck标志,表明这个条件是可能为真还是确定为真。如果recheck为false表示条件确定为真,反之则表示条件可能为真

*union:表示如何在树中组合信息。将一系列的项组合成一个索引项

*compress:表示如何把数据项转换成一种适合存储在索引页中的格式。

*decompress:compress的反向操作

*penalty:返回一个值,用于表示把一个新节点插入到一个树杈上的代价(cost)。返回值应该是一个非负值,如果是负值则被当作0

*picksplit:当一个索引列需要分裂时,这个函数决定哪些节点需要留在旧的索引页中,哪些节点需要移到新的索引页中

*same:判断两个索引项是否相等,相等返回true,否则返回false

*distance:返回索引项p和查询值q之间的“距离”

PostgreSQL数据库已经对一些内置类型实现了GiST索引操作类,在这些类型上可以直接建GiST索引

 

contrib下的以下模块也提供了一些类型的GiST索引的操作类

*btree_gist:使用gist实现的btree

*cube:多维的cube类型

*hstore:一种key/value存储类型

*intarray:一维int4数据的RD-Tree实现

*Itree:树型结构的索引

*pg_trgm:文件相似性的索引

*seg:浮点范围类型的索引

 

SP-GIST索引

SP-GiST是"space-partitioned GiST”的缩写,即空间分区GiST索引。它是从PostgreSQL9.2版本开始提供的一种新索引类型,主要是通过一些新的索引算法提高GiST索引在某个情况下的性能。它与GiST索引一样,是一个通用的索引框架,基于此框架可以开发自定义的空间分区索引。比如可以使用此框架实现以下类型的索引:

*quad-trees

*k-d trees

*radix trees

 

要实现一个自定义的SP-GiST索引操作类,需要实现以下五个用户自定义函数:

*config:返回索引实现中的一些静态信息,如前缀的数据类型的OID、节点label的数据类型的OID等

*choose:选择如何把新的值插入到索引内部tuple中

*picksplit:决定如何在一些叶子tuple上创建一个新的内部tuple

*inner_consistent:在树的搜索过程中返回一系列的节点(树权上的)

*leaf_consistent:如果一个叶子节点满足查询则返回真

 

PostgreSQL数据库已经对一些内置类型实现了SP-GiST索引操作类,在这些类型上可以直接建SP-GiST索引

对于point类型,有两种索引操作类kd_point_ops和quad_point_ops,其中quad_point_ops是默认的索引操作类,在某些场景下,kd_point_ops索引操作类会更高效一些

 

GIN索引

GIN索引是Generalized Inverted Index的缩写,即广义倒排索引。GIN索引通常用于全文检索,即在文章中搜索指定的词。GIN索引中存储了一系列"key,位置列表”对,位置列表中存储了包含此key值的行的列表。同一行的rowid会出现在多个位置列表中

与GiST索引一样,GIN索引也是一个通用的索引框架,基于此框架可以开发自定义的GIN索引

要实现一个自定义的GiST索引操作类,需要实现以下三个用户自定义函数

*compare:比较两个值,根据大小返回负数、0、正数。

*extractValue

*extractQuery

还有以下一些可选的函数

*consistent

*triConsistent

*comparePartial

 

PostgreSQL数据库已经对一些内置的数组类型实现了GIN索引操作类,在这些类型上可以直接建GIN索引

 

插入更新时, GIN索引比较慢,如果要向一张表中插入大量数据,最好先把GIN索引删除,插入数据后再重建GIN索引

把maintenance work mem参数调大,可以更快地完成GIN索引的创建工作

在实际操作中,常常会遇到全文索引返回海量结果的情形,如在查询高频词时。这样的结果集没什么用处,因为从磁盘读取大量记录并对其进行排序会消耗大量资源。为了易于控制这种情况,GIN有一个可配置的结果集大小“软”上限配置参数gin_fuzzy_search_limit,此参数默认为0,表示没有限制;如果设置了非零值,那么返回的结果就是从完整结果集中随机选择的一部分。根据经验,这个参数一般设置为几千到两万比较好,如5000到20000之间

contrib下的以下一些模块也实现了一些gin索引操作类

*btree_gin:实现类型btree的功能

*hstore:存储(key, value)对的一种类型

*intarray:增强int[]

*pg_trgm:文本相似匹配

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: