グローバルインデックスの作成ルールは、インデックスプロパティにGLOBALキーワードを指定することです。ローカルインデックスと比較して、グローバルインデックスの最大の特徴は、グローバルインデックスのパーティションルールがテーブルのパーティションルールと独立していることです。グローバルインデックスでは、独自のパーティションルールとパーティション数を指定でき、必ずしもテーブルのパーティションルールと一致させる必要はありません。
グローバルインデックスの作成
主表にパーティションキーが指定されていない場合、または指定されたパーティション数が1の場合、主表にも1つのパーティションしかありません。このとき、グローバルインデックスのデータと主表データの物理的位置は相互に結びついており、移行やレプリカリーダーの切り替えが発生しても、それらは一体として変換され、中間状態は存在しません。グローバルインデックスのパーティションルールと主表のパーティションルールが同じで、かつパーティション数も同じ場合は、ローカルインデックスを作成することを推奨します。これは、一方ではグローバルインデックスのメンテナンスコストが高いこと、もう一方ではグローバルインデックスが主表のパーティションと同一の物理的位置を保証できないことによるものです。
説明
グローバルインデックスを作成する際、テーブルが SHARDING = 'NONE' プロパティを持つテーブルグループ内にある場合、作成されたグローバルインデックスも同時にそのテーブルグループにバインドされます。テーブルグループプロパティの詳細については、テーブルグループのSHARDINGプロパティの変更を参照してください。
グローバルインデックスの作成
Hashパーティションを使用したパーティションテーブル tbl1_h を作成し、Rangeパーティションを使用したグローバルインデックス 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) GLOBAL
PARTITION BY RANGE(col2)
(PARTITION p0 VALUES LESS THAN(100),
PARTITION p1 VALUES LESS THAN(200),
PARTITION p2 VALUES LESS THAN(300)
);
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 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) GLOBAL;
Query OK, 0 rows affected
パーティションカット
グローバルインデックスのパーティションキーは必ずインデックスキーそのものであるため、グローバルインデックスを使用する際にはインデックスのパーティションキーを指定したクエリ条件が設定されます。インデックスのパーティションルールに基づいてパーティションカットを行うことができ、インデックスキー値を照会した後、インデックステーブルに格納されている主キー情報を利用してメインテーブルのパーティション位置を計算し、メインテーブルに対しても迅速なパーティション位置特定が可能になります。これにより、メインテーブルのすべてのパーティションをスキャンすることを回避できます。したがって、メインテーブルのパーティションキーを指定できないクエリについては、一定の条件下でグローバルインデックスがクエリの検索効率を高速化できます。
例:
obclient> EXPLAIN SELECT /*+index(t1 gkey)*/ * FROM t1 WHERE b=1;
+---------------------------------------------------------------+
| Query Plan |
+---------------------------------------------------------------+
| ========================================================== |
| |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| |
| ---------------------------------------------------------- |
| |0 |DISTRIBUTED TABLE SCAN|t1(GKEY)|4950 |38645 | |
| ========================================================== |
| Outputs & filters: |
| ------------------------------------- |
| 0 - output([t1.A], [t1.B], [t1.C]), filter(nil), rowset=256 |
| access([t1.A], [t1.B], [t1.C]), partitions(p0) |
| is_index_back=true, is_global_index=true, |
| range_key([t1.B], [t1.A]), range(1,MIN ; 1,MAX), |
| range_cond([t1.B = 1]) |
+---------------------------------------------------------------+
上記のクエリでは、まず WHERE 条件の b=1 条件によってグローバルインデックスのパーティション p1 をカットし、次にグローバルインデックステーブルに対して table scan 操作を実行して対応する主キーを取得します。主キーを利用してメインテーブルに対して正確なパーティションスキャンを行い、メインテーブルのすべてのパーティションをスキャンすることを避けます。
Truncateパーティション/パーティション削除がグローバルインデックスに与える影響
Truncateパーティション/パーティション削除は、対応するテーブルのすべてのグローバルインデックスを再構築します(インデックスを削除した後、再作成されます)。
説明
OceanBaseデータベースV4.3.5 BP2以降では、パラメータ _ob_enable_truncate_partition_preserve_global_index を true に設定することで、グローバルインデックスの正確性を保証し、グローバルインデックスを引き続き使用できます。有効にしない場合、Truncateパーティション/パーティション削除後のグローバルインデックスへの影響は上記の通りです。