暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

DM全局索引和局部索引

原创 达梦官档 2023-05-26
2099

从分区的角度进行分类,可分为全局索引和局部索引。全局索引和局部索引均为二级索引,专门用于水平分区表中。

当分区子表个数较多、索引列的选择率较好、没有使用分区裁剪优化等因素时,执行计划会倾向于使用全局索引进行查询。但由于全局索引的日常维护成本高于局部索引。因此用户可根据实际应用场景权衡利弊之后再在全局索引和局部索引中进行选择。

● 全局索引:全局索引是以整张表的数据为对象而建立的索引。

指定 GLOBAL 关键字创建的索引即为全局索引。创建全局索引时,会在水平分区表的主表上创建全局索引和在每个子表上创建全局本地索引。索引数据存储在全局索引上。全局本地索引的命名规则为:INDEX+ 全局本地索引 ID_全局索引 ID。例如:全局索引 IDX1 的 ID 为 3504,全局本地索引的 ID 为 3506,那么全局本地索引的名称为 INDEX3506_3504。

全局索引具体分为两种:全局非分区索引和全局分区索引。指定了 <PARTITION 子句 > 的索引即为分区索引。只有 DMDPC 功能支持分区索引。

全局非分区索引可用于除 DMDPC 以外的任何环境中。

例 1 创建全局非分区索引

//创建表
drop table t1;
create table t1(c1 int, c2 int, c3 int)  partition by range(c1)
(
	partition p1 values less than(100),
	partition p2 values less than(200),
partition p3 values less than(maxvalue)
);
//创建全局分区索引
create index idx1 on t1(c2) global;
//在WHERE中指定索引列,可使用索引idx1查询
explain select * from t1 where c2 = 130;
1   #NSET2: [1, 1, 24]
2     #PRJT2: [1, 1, 24]; exp_num(4), is_atom(FALSE)
3       #PARALLEL: [1, 1, 24]; scan_type(FULL), key_num(0, 0, 0), simple(0)
4         #BLKUP2: [1, 1, 24]; IDX1(T1)
5           #SSEK2: [1, 1, 24]; scan_type(ASC), IDX1(T1), scan_range[130,130]
//直接对分区子表查询,则使用全局本地索引
explain select * from t1_p1 where c2 = 130;
1   #NSET2: [1, 1, 24]
2     #PRJT2: [1, 1, 24]; exp_num(4), is_atom(FALSE)
3       #BLKUP2: [1, 1, 24]; INDEX3505_3504(T1_P1)
4         #SSEK2: [1, 1, 24]; scan_type(ASC), INDEX3505_3504(T1_P1), scan_range[130,130]

全局分区索引专门用于 DMDPC 环境中。索引经 <PARTITION 子句 > 分区之后,全局索引便有了分区子索引。索引数据存储在分区子索引上。

分区子索引的命名规则为:全局索引名_索引分区名。例如:全局索引名称为 IDX1,索引分区名为 P1、P2,那么分区子索引名称为 IDX1_P1 和 IDX1_P2。

分区子索引是全局分区索引的组成部分,使用全局索引即可使用到分区子索引。不支持单独使用分区子索引进行查询。

例 2 在 DMDPC 环境中创建全局分区索引

//创建表空间
create tablespace ts1 datafile 'opt/ts/ts01.dbf' size 128 storage (on raft_1);
create tablespace ts2 datafile 'opt/ts/ts02.dbf' size 128 storage (on raft_2);
//创建表
drop table t1;
create table t1(c1 int, c2 int, c3 int)  partition by range(c1)
(
	partition p1 values less than(100),
	partition p2 values less than(200),
partition p3 values less than(maxvalue)
);
//创建全局分区索引
drop index idx1;
create index idx1 on t1(c2) global partition by range(c2)
(
  partition p1 values less than(1000) storage(on ts2) ,
  partition p2 values less than(maxvalue) storage(on ts1)
);
//使用索引idx1查询
explain select * from t1 where c2 = 130;  //当数据量很大时
explain select * from t1 index idx1 where c2 = 130;  //或直接指定全局索引
1   #NSET2: [2, 1, 24]
2     #ERECV: [2, 1, 24]; stask_no(-1), l_stask_no(1), n_key(0), in_turn(0), trig(0)
3       #ESEND: [2, 1, 24]; stask_no(1), type(DIRECT), sites(2:1,1:1), sql_invoke(0), pwj_opt(0), table(-); INFO_BITS(0x8)
4         #PRJT2: [2, 1, 24]; exp_num(4), is_atom(FALSE)
5           #PARALLEL: [2, 1, 24]; scan_type(FULL), key_num(0, 0, 0), simple(0)
6             #BLKUP2: [2, 1, 24]; IDX1(T1)
7               #ERECV: [2, 1, 24]; stask_no(1), l_stask_no(0), n_key(0), in_turn(0), trig(0)
8                 #ESEND: [2, 1, 24]; stask_no(0), type(ROWID), sites(2:1,1:1), sql_invoke(0), pwj_opt(0), table(T1) empty_type(ERROR); INFO_BITS(0xc)
9                   #GI: [2, 1, 24]; policy(RANDOM), gi_unit[0..0], scan_type[0](FULL)
10                    #SSEK2: [2, 1, 24]; scan_type(ASC), IDX1(T1), scan_range[130,130]
//直接对分区子表查询,则使用全局本地索引
explain select * from t1_p1 where c2 = 130;
1   #NSET2: [1, 1, 24]
2     #PRJT2: [1, 1, 24]; exp_num(4), is_atom(FALSE)
3       #BLKUP2: [1, 1, 24]; INDEX3505_3504(T1_P1)
4         #SSEK2: [1, 1, 24]; scan_type(ASC), INDEX3505_3504(T1_P1), scan_range[130,130]

● 局部索引:局部索引是在分区表的每个分区上创建的索引。

未指定 GLOBAL 关键字创建的索引即为局部索引。局部索引暂时不支持分区。创建局部索引时,会在水平分区表的主表上创建局部索引和在每个子表上创建子表局部索引。索引数据存储在子表局部索引上。

子表局部索引的命名规则为:INDEX+ 子表局部索引 ID_局部索引 ID。例如:局部索引 IDX1 的 ID 为 3504,子表局部索引的 ID 为 3506,那么子表局部索引的名称为 INDEX3506_3504。

例 创建局部索引

//创建表
drop table t1;
create table t1(c1 int, c2 int, c3 int)  partition by range(c1)
(
	partition p1 values less than(100),
	partition p2 values less than(200),
partition p3 values less than(maxvalue)
);
//创建局部索引,必须缺省GLOBAL关键字
create index idx1 on t1(c2);
//在WHERE中指定索引列,可使用索引idx1查询
explain select * from t1 where c2 = 130;
1   #NSET2: [1, 1, 24]
2     #PRJT2: [1, 1, 24]; exp_num(4), is_atom(FALSE)
3       #PARALLEL: [1, 1, 24]; scan_type(FULL), key_num(0, 0, 0), simple(0)
4         #BLKUP2: [1, 1, 24]; IDX1(T1)
5           #SSEK2: [1, 1, 24]; scan_type(ASC), IDX1(T1), scan_range[130,130]
//直接对分区子表查询,则使用子表局部索引
explain select * from t1_p1 where c2 = 130;
1   #NSET2: [1, 1, 24]
2     #PRJT2: [1, 1, 24]; exp_num(4), is_atom(FALSE)
3       #BLKUP2: [1, 1, 24]; INDEX3505_3504(T1_P1)
4         #SSEK2: [1, 1, 24]; scan_type(ASC), INDEX3505_3504(T1_P1), scan_range[130,130]
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论