ローカルインデックスはパーティションインデックスとも呼ばれ、インデックスを作成する際のパーティションキーワードはLOCALです。ローカルインデックスのパーティションキーはテーブルのパーティションキーと同じであり、ローカルインデックスのパーティション数もテーブルのパーティション数と同じです。そのため、ローカルインデックスのパーティショニングメカニズムはテーブルのものと同じです。
説明
ローカルインデックスは、単一のパーティション上のデータに対して作成されるインデックスであるため、ローカルインデックスのキー値とテーブル内のデータは一対一で対応します。つまり、ローカルインデックスのあるパーティションは必ずテーブルの特定のパーティションに対応し、両者は同じパーティションルールを持ちます。そのため、ローカル一意インデックスは、パーティション内部での一意性を保証することはできても、テーブルデータ全体のグローバルな一意性を保証することはできません。
ローカル一意インデックスを使用してデータの一意性を制約する場合、そのインデックスにはテーブルのパーティションキーを含める必要があります。
注意
MySQLモードでは、インデックスプロパティキーワードが指定されていない場合、デフォルトでLOCALプロパティが適用され、作成されるインデックスはローカルインデックスとなります。
一意インデックスには、テーブルのパーティション関数に含まれるすべての列を含める必要があります。
例
ローカルインデックスの作成
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主キーのないパーティションテーブル
tbl2_hを作成し、そのための全文インデックスを作成します。CREATE TABLE tbl2_h(col1 INT, col2 TEXT, FULLTEXT INDEX(col2)) PARTITION BY HASH(col1) PARTITIONS 5;全文インデックスの詳細については、全文インデックスを参照してください。
ローカル一意インデックスの作成
非テンプレートの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 IN(1,3),
SUBPARTITION sp1 VALUES IN(4,6),
SUBPARTITION sp2 VALUES IN(7,9)),
PARTITION p1 VALUES LESS THAN(200)
(SUBPARTITION sp3 VALUES IN(1,3),
SUBPARTITION sp4 VALUES IN(4,6),
SUBPARTITION sp5 VALUES IN(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