关键字:
索引、btree、hash、bitmap、GIN、人大金仓、KingbaseES
Btree索引
Btree是索引是最常见的索引类型,也是KES的默认索引,适用于范围查询和优化排序操作。Btree索引支持测操作符包括: >,<,>=,<=,=,IN,LIKE等,此外,优化器也会优先选择Btree来对ORDER BY、MIN、MAX、MERGE JOIN进行有序操作。
Hash索引
Hash索引查询效率比Btree高得多,但只适用于等值查询。由于Hash索引是通过比较哈希值来做定位,因此当查询列上有较大比例的重复值时,会带来严重的哈希冲突,进而影响查询速度,这种情况下就不建议使用Hash索引。
Bitmap索引
① Bitmap索引(执行节点)
用一个位图来存放记录索引信息,1表示某个属性对应的值存在,0表示不存在,适用于值比较单一(比如:性别字段)的情况。
为了组合多个索引,系统扫描每个需要的索引,然后在内存里组织一个BITMAP,它将给出索引扫描出的数据在数据表中的物理位置。然后,再根据查询的需要,把这些位图进行AND或者OR的操作并得出最终的BITMAP。最后,检索数据表并返回数据行。表的数据行是按照物理顺序进行访问的,因为这是位图的布局,这就意味着任何原来的索引的排序都将消失。如果查询中有ORDER BY子句,那么还将会有一个额外的排序步骤。因为这个原因,以及每个额外的索引扫描都会增加额外的时间,这样优化器有时候就会选择使用简单的索引扫描,即使有多个索引可用也会如此。
Bitmap索引主要适用于当表具有很多属性且查询可能会涉及其中任意组合时的情况。
优化器为普通索引建立位图表,主要包括2种扫描方式:
Bitmap Index Scan:用来在内存中创建一个位图表,每一个Bit表示一个与过滤条件有关的页面。Bit上有数据为1,不可能为0。通过位图扫描,能够快速确定某个值在哪些记录上存在与否。
Bitmap Heap Scan:Bitmap上检索到的记录都对应其rowid,用这个rowid到关系表上去查找完整的记录信息并过滤。
② Bitmap索引(索引AM)
使用保存在磁盘上的位图结构保存索引信息。与执行节点的Bitmap索引的区别是:执行节点的Bitmap索引是将计算过程需要的数据以位图的形式进行运算,而索引AM的Bitmap索引是将索引信息压缩存储在磁盘上。
在创建Bitmap索引时,系统将扫描目标列,创建内部表并保存列中每一个独特值。然后针对每一个独特值,按其原始数据在表中的位置创建位图并压缩存储在磁盘中。在查询过程中,系统将先查询内部表中记录的目标值位图页的位置,然后在该位置读取目标值位图信息。需要注意的是,考虑到Bitmap索引的存储结构,对Bitmap索引相关列的Update操作将会导致Bitmap索引的解压缩和重压缩,因此性能会较为缓慢。
Bitmap索引(索引AM) 的限制为:不会进行Update操作的的数据列,且列的基数值在1-10000之间(若为多列索引,则基数值为各列的基数的乘积)。
GIN索引
GIN是通用倒排序索引(Generalized Inverted Index),它是一个存储对(Key,postion list)的集合,其中Key是一个键值,而postion list是包含Key的位置值。比如('Tom','10:25 14:3 29:5') 就表示关键字'Tom'在这些位置(元组TID)上存在。当我们用关键字'Tom'去查询的时候,能一下就定位到包含关键字的元组有这三个。
GIN索引适用于包含多个组合值的查询,如数组、全文检索等。
GiST索引
GiST是通用的搜索树(Generalized Search Tree)。它是一种平衡树结构的访问方法,在系统中作为一个基本模版,可以使用它实现任意索引模式。B-trees,R-trees和许多其它的索引模式都可以用GiST实现。
GiST索引适用于多维数据类型和集合数据类型,可以用来做位置搜索,如包含、相交、左边、右边等。
SP-GiST索引
SP-GiST空间分区GiST索引。它主要是通过一些新的索引算法提高GiST索引在某个情况下的性能。要实现一个自定义的SP-Gist索引,需要实现5个自定义函数:
① Config:返回索引实现中的一些静态信息
② Choose:选择如何把新的值插入到索引内部tuple中
③ Picksplit:决定如何在一些叶子tuple上创建一个新的内部tuple
④ Inner_consistent:在树的搜索过程中返回一系列树杈上的节点
⑤ Leaf_consistent:返回叶子节点是否满足查询
SP-GiST适用于空间可以递归分割成不相交区域的结构,包括四叉树、k-D树和基数树。KES在如下表所示的类型上可以直接创建SP-GiST索引:
名称 | 数据类型 | 索引操作符 |
quad_point_ops | Point | <<,<@,<^,>>,>^,~= |
kd_point_ops | Point | <<,<@,<^,>>,>^,~= |
range_ops | Range | &&,&<,&>,- | -,<<,<@,=,>>,@> |
text_ops | Text | <,<=,=,>,>=,~<=~,~<~,~>=~,~>~ |
BRIN索引
BRIN索引是块范围索引的简称,由于其存储了表的连续数据块区间以及对应的数据取值范围,因此BRIN索引的体积和维护代价相比其他索引低很多。
BRIN索引适用于存储流式的数据日志 。例如:按照时间插入的数据。由于数据是按照时间插入,因此数据块上记录的范围信息很少会出现交叉情况,索引过滤后需要比较的数据块也会少很多;反之,如果数据交叉严重,通过索引无法过滤掉任何一个数据块时,操作起来会比全表扫描更加耗时。
参考资料
KingbaseES数据库SQL调优指南