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

OceanBase 分区建立局部索引

Ty3306 2023-02-05
1297

 分区建立局部索引
局部索引又名分区索引,创建索引的分区关键字是 LOCAL。局部索引的分区键等同于表的分区键,局部索引的分区数等同于表的分区数,所以局部索引的分区机制和表的分区机制一样
案例:
obclient> CREATE TABLE t1(a int primary key, b int) PARTITION BY hash(a) partitions 5;
obclient> CREATE INDEX idx ON t1(b) local;
 
局部唯一索引案例:
如果要使用局部唯一索引去对数据唯一性做约束,那么局部唯一索引中必须包含表分区键
下述示例语句为给分区表 t2 创建局部唯一索引 uk
obclient> CREATE TABLE t2(a int primary key, b int) PARTITION BY hash(a) partitions 5;
obclient> CREATE UNIQUE INDEX uk ON t2(b) LOCAL;
ERROR 1503 (HY000): A UNIQUE INDEX must include all columns in the table's partitioning function
obclient> CREATE UNIQUE INDEX uk2 on t2(b, a) local;
Query OK, 0 rows affected (5.32 sec)
 
局部索引同样支持分区裁剪
(1)使用分区裁剪的前提条件是查询条件中能够指定分区键,可以减少在查询过程中读取的分区个数,从而能够提高查询检索的效率
obclient> EXPLAIN SELECT /*+index(t1 idx)*/ b FROM t1 WHERE b=1 AND a=1\G
*************************** 1. row ***************************
Query Plan: =====================================
|ID|OPERATOR |NAME |EST. ROWS|COST|
-------------------------------------
|0 |TABLE GET|t1(idx)|1 |52 |
=====================================
Outputs & filters:
-------------------------------------
0 - output([t1.b]), filter(nil),
access([t1.b]), partitions(p1)
1 row in set (0.01 sec)
 
(2)如果在查询中,没有指定分区键,那么局部索引将无法进行分区裁剪,这时会扫描所有分区,增加额外的扫描代价。下述示例语句为查询条件中不指定分区键:

obclient> EXPLAIN SELECT /*+index(t1 idx)*/ b FROM t1 WHERE b=1\G
*************************** 1. row ***************************
Query Plan: ====================================================
|ID|OPERATOR |NAME |EST. ROWS|COST|
----------------------------------------------------
|0 |EXCHANGE IN DISTR | |4950 |3551|
|1 | EXCHANGE OUT DISTR |:EX10000|4950 |3083|
|2 | PX PARTITION ITERATOR| |4950 |3083|
|3 | TABLE SCAN |t1(idx) |4950 |3083|
====================================================
Outputs & filters:
-------------------------------------
0 - output([t1.b]), filter(nil)
1 - output([t1.b]), filter(nil), dop=1
2 - output([t1.b]), filter(nil)
3 - output([t1.b]), filter(nil),
access([t1.b]), partitions(p[0-4])
1 row in set (0.01 sec)
 
十二 全局索引
全局索引的创建规则是在索引属性中指定 GLOBAL 关键字。与局部索引相比,全局索引最大的特点是全局索引的分区规则跟表分区是相互独立的,全局索引允许指定自己的分区规则和分区个数,不一定需要跟表分区规则保持一致
案例:

obclient> CREATE TABLE t1(a int PRIMARY KEY, b int, c int) PARTITION BY hash(a) partitions 5;
obclient> CREATE INDEX gkey ON t1(b) GLOBAL PARTITION BY range(b) (
partition p0 VALUES less than (1),
partition p1 VALUES less than (2),
partition p2 VALUES less than (3)
);
 
全局索引的分区键一定是索引键本身,因此在使用全局索引的过程中就会指定索引分区键的查询条件,我们可以针对索引的分区规则进行分区裁剪,在查询到索引键值后可以利用索引表中存储的主键信息计算出主表的分区位置,进而对主表也能进行快速的分区定位,避免扫描主表的所有分区,因此对于无法指定主表分区键的查询而言,全局索引在一定条件下能够加速查询的检索效率。
案例如下:

obclient> EXPLAIN SELECT /*+index(t1 gkey)*/ * FROM t1 WHERE b=1\G
*************************** 1. row ***************************
Query Plan: ==========================================
|ID|OPERATOR |NAME |EST. ROWS|COST |
------------------------------------------
|0 |TABLE LOOKUP|T1 |4950 |38645|
|1 | TABLE SCAN |T1(GKEY)|4950 |1115 |
==========================================
Outputs & filters:
-------------------------------------
0 - output([T1.A], [T1.B], [T1.C]), filter(nil),
partitions(p[0-4])
1 - output([T1.A]), filter(nil),
access([T1.A]), partitions(p1)
 
十三 使用索引
使用限制
在分布式环境中,全局索引不可避免的会涉及到分布式事务和跨机的查询,因此全局索引依赖 GTS 维护全局的一致性快照,所以全局索引只能在 GTS 开启的时候使用。如果没有开启 GTS,则创建全局索引失败
案例:
obclient> SET GLOBAL ob_timestamp_service=LTS;
Query OK, 0 rows affected (0.06 sec)
obclient> CREATE TABLE t1(a int, b int, PRIMARY KEY(a));
Query OK, 0 rows affected (0.17 sec)
obclient> CREATE INDEX gkey ON t1(b) PARTITION BY range(b) (PARTITION p0 VALUES LESS THAN (1), PARTITION p1 VALUES LESS THAN (2), PARTITION p2 VALUES LESS THAN(3));
ERROR 1235 (0A000): create global index when GTS is off not supported
 
由于 OceanBase 数据库的表是索引组织表(IOT),对于分区表而言,为了保证指定主键的查询能很快定位到表所在的分区,所以分区键必须是主键的子集。如果需要在分区表上创建局部分区唯一索引(Local Partitioned Unique Index),则该索引键需要包含主表的分区键,而对于全局分区唯一索引(Global Partitioned Unique Index)并没有这个限制

obclient> CREATE TABLE test(pk int,c2 int ,c3 int, PRIMARY KEY(pk)) PARTITION BY hash(pk) partitions 5;
Query OK, 0 rows affected (0.20 sec)
obclient> CREATE UNIQUE INDEX idx ON test(c2) LOCAL;
ERROR 1503 (HY000): A UNIQUE INDEX must include all columns in the table's partitioning function
obclient> CREATE UNIQUE INDEX idx ON test(c2, pk) LOCAL;
Query OK, 0 rows affected (5.34 sec)
obclient> DROP INDEX idx ON test;
Query OK, 0 rows affected (0.02 sec)
obclient> CREATE UNIQUE INDEX idx ON test(c2) GLOBAL;
Query OK, 0 rows affected (17.47 sec)
 

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论