局部索引又名分区索引,创建索引的分区关键字是 LOCAL。局部索引的分区键等同于表的分区键,局部索引的分区数等同于表的分区数,所以局部索引的分区机制和表的分区机制一样。

    下述示例语句为给分区表 t1 创建一个局部索引 idx:

    1. obclient> CREATE TABLE t1(a int primary key, b int) PARTITION BY hash(a) partitions 5;
    2. obclient> CREATE INDEX idx ON t1(b) local;

    局部索引是针对单个分区上的数据创建的索引,因此局部索引的索引键值跟表中的数据是一一对应的关系,即局部索引上的一个分区一定对应到一个表分区,它们具有相同的分区规则,因此对于局部唯一索引而言,它只能保证分区内部的唯一性,而无法保证表数据的全局唯一性。如果要使用局部唯一索引去对数据唯一性做约束,那么局部唯一索引中必须包含表分区键。

    下述示例语句为给分区表 t2 创建局部唯一索引 uk:

    1. obclient> CREATE TABLE t2(a int primary key, b int) PARTITION BY hash(a) partitions 5;
    2. obclient> CREATE UNIQUE INDEX uk ON t2(b) LOCAL;
    3. ERROR 1503 (HY000): A UNIQUE INDEX must include all columns in the table's partitioning function
    4. obclient> CREATE UNIQUE INDEX uk2 on t2(b, a) local;
    5. Query OK, 0 rows affected (5.32 sec)

    在 OceanBase 中,局部索引同样支持分区裁剪。使用分区裁剪的前提条件是查询条件中能够指定分区键,可以减少在查询过程中读取的分区个数,从而能够提高查询检索的效率。下述示例语句为查询条件中指定分区键:

    1. obclient> EXPLAIN SELECT /*+index(t1 idx)*/ b FROM t1 WHERE b=1 AND a=1\G
    2. *************************** 1. row ***************************
    3. Query Plan: =====================================
    4. |ID|OPERATOR |NAME |EST. ROWS|COST|
    5. -------------------------------------
    6. |0 |TABLE GET|t1(idx)|1 |52 |
    7. =====================================
    8. Outputs & filters:
    9. -------------------------------------
    10. 0 - output([t1.b]), filter(nil),
    11. access([t1.b]), partitions(p1)
    12. 1 row in set (0.01 sec)

    如果在查询中,没有指定分区键,那么局部索引将无法进行分区裁剪,这时会扫描所有分区,增加额外的扫描代价。下述示例语句为查询条件中不指定分区键:

    1. obclient> EXPLAIN SELECT /*+index(t1 idx)*/ b FROM t1 WHERE b=1\G
    2. *************************** 1. row ***************************
    3. Query Plan: ====================================================
    4. |ID|OPERATOR |NAME |EST. ROWS|COST|
    5. ----------------------------------------------------
    6. |0 |EXCHANGE IN DISTR | |4950 |3551|
    7. |1 | EXCHANGE OUT DISTR |:EX10000|4950 |3083|
    8. |2 | PX PARTITION ITERATOR| |4950 |3083|
    9. |3 | TABLE SCAN |t1(idx) |4950 |3083|
    10. ====================================================
    11. Outputs & filters:
    12. -------------------------------------
    13. 0 - output([t1.b]), filter(nil)
    14. 1 - output([t1.b]), filter(nil), dop=1
    15. 2 - output([t1.b]), filter(nil)
    16. 3 - output([t1.b]), filter(nil),
    17. access([t1.b]), partitions(p[0-4])
    18. 1 row in set (0.01 sec)