ローカルインデックスはパーティションインデックスとも呼ばれ、インデックスを作成する際のパーティションキーワードは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