关键字:
本地索引,全局索引、人大金仓、KingbaseES
1. 分区索引的概念
常见的分区索引包含本地索引与全局索引,本地索引是指创建在表中的数据分区上的索引,而全局索引则是跨越整个表的索引,与表的分区结构无关,下面大概的从不同的方面简单的介绍一下这两种索引。
1.1 本地索引
本地索引:每个分区都有一个独立的索引。该索引仅为该分区上的数据建立。每个分区的索引都相对较小,仅包含该分区的数据。
性能优点:本地索引通常情况下比全局索引的查询性能更好,因为他们只需要访问查询相关的分区。
维护优点:维护本地索引时,只需处理和特定分区相关的索引,这使得维护大表格变得更加可行
1.2 全局索引
全局索引:跨越了整个表的索引,不考虑表的分区的结构,这种索引适用于在整个表上执行的查询
性能考虑:全局索引的性能可能在某些情况下略低于本地索引,特别是在查询时需要跨越多个分区的数据时。
2. 两种索引的区别
2.1 本地索引
本地索引又叫局部索引,主要依赖于关键字local,具体的在某个分区上创建本地索引的语法如下:
CREATE INDEX range_index_tab1_index_p1 on range_index_tab1_p1 (i) LOCAL;
和创建普通的索引差别不大,只是需要将原来具体的表名详细指定到分区表名,(i)即为分区键,local即为本地索引关键字
不知道具体的分区表名的,可以使用如下命令查询
\d+ range_index_tab1
如下图所示
2.1.1 本地索引在合并分区上的介绍
先创建一个基本的本地索引,建表语句与创建索引语句如下,在分区p1和分区p4上创建本地索引:
CREATE TABLE range_index_tab1(
i NUMBER,
j NUMBER,
f VARCHAR2(20)
)PARTITION BY RANGE(i)
(
PARTITION p1 VALUES LESS THAN(10),
PARTITION p2 VALUES LESS THAN(20),
PARTITION p3 VALUES LESS THAN(30),
PARTITION p4 VALUES LESS THAN(40)
);
CREATE INDEX range_index_tab1_index_p1 on range_index_tab1_p1 (i) LOCAL;
CREATE INDEX range_index_tab1_index_p4 on range_index_tab1_p4 (i) LOCAL;
如下图所示为创建的分区索引的状态,默认不指定索引存储结构的话就是btree结构,这里不影响具体结果。
此时,分别将分区p1,p2合并成p2,分区p3,p4合并成p4,查看具体的分区索引结果,执行语句如下:
alter table range_index_tab1 merge partitions p1 ,p2 into partition p2;
可以看到,原先属于p1分区的本地索引消失了,在新的p2分区中也并没有体现。
此时,再将p3与p4分区合并,执行语句如下:
alter table range_index_tab1 merge partitions p3 ,p4 into partition p4;
可以看到,分区索引仍然存在。
结论:在合并分区中,合并后的分区如果有复用原分区中的本地索引,且合并后的分区名与原分区中的最后一个分区相同时,此时分区表会维护合并分区的索引,相反,若合并后的分区名不同于原分区或分区名不在最后一个,此时,分区表就不会维护该合并分区的索引。
合并分区后的名字不同于原分区时的案例如下:
此时,p3,p4中p4存在分区,合并分区后的名字为p5,相当于没有复用原分区,因此索引也就不复存在
2.1.2 本地索引在分裂分区上的介绍
还是相同的案例,在p1分区上创建本地索引,执行语句如下
CREATE TABLE range_index_tab2(
i NUMBER,
j NUMBER,
f VARCHAR2(20)
)PARTITION BY RANGE(i)
(
PARTITION p1 VALUES LESS THAN(10)
);
CREATE INDEX range_index_tab2_index_p1 on range_index_tab2_p1 (i) LOCAL;
ALTER TABLE range_index_tab2 SPLIT PARTITION p1 AT(5) INTO (PARTITION p1,PARTITION p2);
将分区p1拆分为p1与p2两个分区,在查看这两个分区上的索引分布情况,如下图所示,可以看到,两个拆分后的分区都不存在本地索引。
结论:分裂分区无论分裂之前的分区本地索引怎么分布,最终拆分后都不会有索引,因为拆分分区并没有复用原来的分区,实际上拆分后的分区属于是新的分区。
3、全局索引
当使用全局索引的时候,具体的使用规则就比较多了。先来看一个具体的例子
CREATE UNIQUE INDEX range_index_tab3_index on range_index_tab3 (j) GLOBAL;
- 全局索引的创建必须加上unique关键字
- 全局索引的索引键值必须要不同于分区表的分区键值,否则无法创建全局索引,就会变成普通的表的索引(例如键值与分区键相同)
- 全局索引必须要加上global关键字
- 全局索引与具体分区无关,与表有关
下面用一个具体的全局索引的例子来介绍一下全局索引:
CREATE TABLE range_index_tab3(
i NUMBER,
j NUMBER,
f VARCHAR2(20)
)PARTITION BY RANGE(i)
(
PARTITION p1 VALUES LESS THAN(10),
PARTITION p2 VALUES LESS THAN(20),
PARTITION p3 VALUES LESS THAN(MAXVALUE)
);
CREATE UNIQUE INDEX range_index_tab3_index on range_index_tab3 (j) GLOBAL;
这里,在对分区表进行拆分或者是合并的时候,都需要涉及到一个更新索引的关键字,update indexes,这里加不加这两种关键字的结果是完全不一样的。
3.1不加update indexes
这里对p1和p2分区进行合并,执行语句如下
ALTER TABLE range_index_tab3 merge PARTITIONs p1,p2 INTO PARTITION p2;
此时,显示全局索引不可用,如果需要恢复全局索引的可用性,就需要重建全局索引,执行语句如下,索引恢复原样:
REINDEX INDEX range_index_tab3_index;
3.2 加update indexes
此时,将p3分区进行拆分,执行如下语句
alter table range_index_tab3 split partition p3 into (partition p3_a values LESS THAN(30),partition p3_b)update indexes;
此时,表中原来的全局索引可以正常使用。
4. 全局索引和普通索引的区别
因为全局索引和普通索引都是创建于一张表的,所以放在一起进行比较一下。
首先来看语法:
全局索引:
CREATE UNIQUE INDEX range_range_tab5_index on range_range_tab5 (j) GLOBAL;
普通索引:
CREATE INDEX range_range_tab5_index2 on range_range_tab5 (j);
对表结构的影响如下所示:
全局索引:
在具体的表分区中是没有索引的标识的,只作用于表。
普通索引:
在具体的分区中也能够看到普通索引的标识,在表结构中也能看到,同时作用于表分区与表,且没有global字样。
参考资料
《KingbaseES SQL语言参考手册》




