ローカルインデックスはパーティションインデックスとも呼ばれ、インデックスを作成する際のパーティションキーにはLOCALが使用されます。ローカルインデックスのパーティションキーはテーブルのパーティションキーと同一であり、またローカルインデックスのパーティション数もテーブルのパーティション数と同じです。そのため、ローカルインデックスのパーティショニングメカニズムはテーブルのパーティショニングメカニズムと同じです。
説明
ローカルインデックスとは、単一のパーティション上のデータに対して作成されるインデックスであり、そのためインデックスキー値とテーブル内のデータとは一対一の対応関係になります。つまり、ローカルインデックス上のあるパーティションは必ずテーブルのパーティションに対応し、両者は同一のパーティションルールを共有します。したがって、ローカル一意インデックスはパーティション内部での唯一性を保証することはできますが、テーブルデータ全体のグローバルな唯一性を保証することはできません。
ローカル一意インデックスを使用してデータの唯一性を制約する場合、そのインデックスにはテーブルのパーティションキーを含める必要があります。
注意
Oracleモードでは、インデックス属性キーが指定されていない場合、デフォルトのインデックス属性はGLOBALであり、作成されるインデックスはグローバルインデックスであり、かつインデックステーブルにはパーティションが1つしか存在しません。
一意インデックスには、テーブルのパーティション関数に含まれるすべての列を含める必要があります。
例
ローカルインデックスの作成
Hashパーティションを使用したパーティションテーブル tbl1_h を作成し、その上にローカルインデックス tbl1_h_idx1 を作成します。
obclient> CREATE TABLE tbl1_h(col1 INT PRIMARY KEY,col2 INT)
PARTITION BY HASH(col1) PARTITIONS 5;
Query OK, 0 rows affected
obclient> CREATE INDEX tbl1_h_idx1 ON tbl1_h(col2) LOCAL;
Query OK, 0 rows affected
ローカル一意インデックスの作成
テンプレート化されていないRange + Listパーティションテーブル tbl2_f_rl を作成し、その上にローカル一意インデックス tbl2_f_rl_idx1 を作成します。
obclient> CREATE TABLE tbl2_f_rl(col1 INT,col2 INT)
PARTITION BY RANGE(col1)
SUBPARTITION BY LIST(col2)
(PARTITION p0 VALUES LESS THAN(100)
(SUBPARTITION sp0 VALUES(1,3),
SUBPARTITION sp1 VALUES(4,6),
SUBPARTITION sp2 VALUES(7,9)),
PARTITION p1 VALUES LESS THAN(200)
(SUBPARTITION sp3 VALUES(1,3),
SUBPARTITION sp4 VALUES(4,6),
SUBPARTITION sp5 VALUES(7,9))
);
Query OK, 0 rows affected
obclient> CREATE UNIQUE INDEX tbl2_f_rl_idx1 ON tbl2_f_rl(col1,col2) LOCAL;
Query OK, 0 rows affected
パーティションクリッピング
OceanBaseデータベースでは、ローカルインデックスでもパーティションクリッピングがサポートされています。パーティションクリッピングを使用するための前提条件は、クエリ条件でパーティションキーを指定できることです。これにより、クエリ処理中に読み取るパーティション数を減らすことができ、クエリ検索の効率を向上させることができます。
クエリ条件でパーティションキーを指定したパーティションクリッピングの例は以下のとおりです:
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
クエリでパーティションキーが指定されていない場合、ローカルインデックスではパーティションクリッピングを行うことができず、すべてのパーティションがスキャンされるため、追加のスキャンコストが発生します。
クエリ条件でパーティションキーが指定されていない場合、パーティションクリッピングを行うことはできません。例:
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