パーティションテーブルの標準的なインデックスはローカルインデックスで、単一のパーティション内のデータのみをカバーします。つまり、パーティションキーでフィルタリングしないクエリはすべてのパーティションをスキャンする必要があり、結果はグローバルにソートされません。また、一意性制約にはすべてのパーティションキーを含める必要があります。グローバルセカンダリインデックス (GSI) は、すべてのパーティションにまたがることでこれらの制約を解消し、任意のカラムを効率的にクエリでき、パーティションキーを含めずに一意性を強制できます。
この機能を使用するには、クォータセンターにアクセスしてください。[クォータ ID] polardb_mysql_gsi でクォータを検索し、[操作] 列の [申請] をクリックします。
ローカルインデックスの課題
ローカルインデックスは、そのテーブルと同じ方法でパーティション分割されます。各インデックスパーティションは対応するテーブルパーティションのみをカバーするため、データは各パーティション内でソートされますが、パーティション間ではソートされません。これにより、パーティションキーを含まないクエリでは次の 3 つの問題が発生します。
-
全パーティションスキャン:すべてのパーティションがスキャンされるため、パーティション数の増加に伴って読み込み増幅が発生します。
-
グローバルな順序の保証なし:ソートされたパーティションからの結果はグローバルにソートされないため、追加のソート処理が必要になる場合があります。
-
一意性インデックスの制約:ローカルな一意性インデックスは、パーティション間で一意性を強制するために、すべてのパーティションキーを含める必要があります。
GSI はパーティション分割されません。すべてのパーティションのデータから構築され、グローバルにソートされます。GSI のグローバルな一意性インデックスは、すべてのパーティションキーを含める必要がありません。
GSI を使用すべき状況
|
シナリオ |
推奨されるインデックスタイプ |
理由 |
|
パーティションキー以外のカラムで頻繁にフィルタリングするクエリ |
GSI |
全パーティションスキャンを回避 |
|
パーティションキー以外のカラムに対するグローバルな一意性制約 |
GSI |
ローカルな一意性インデックスにはすべてのパーティションキーが必要 |
|
パーティションのアーカイブ頻度が低い (例:月次パーティションを数年間保持) |
GSI |
クエリパフォーマンスの向上、パーティションチャーンの削減 |
|
クエリがほぼ単一のパーティションに限定される |
ローカルインデックス |
書き込みオーバーヘッドの削減 |
サポートされるバージョン
この機能を使用するには、PolarDB for MySQL クラスターがバージョン 8.0.2、リビジョン 8.0.2.2.7 以降である必要があります。クラスターのバージョンを確認する方法については、「バージョン番号のクエリ」をご参照ください。
制限事項
-
GSI は InnoDB パーティションテーブルでのみサポートされます。ハイブリッドパーティションテーブルはサポートされていません。
-
GSI は全文インデックスまたは空間インデックスにはできません。
-
GSI は圧縮テーブル、一時テーブル、暗号化テーブルではサポートされていません。REDUNDANT または COMPRESSED 行フォーマットを使用するテーブルもサポートされていません。
-
GSI を持つテーブルは生成カラムをサポートしていません。
-
パーティションレベルの DDL 操作 (レンジまたは LIST パーティションの追加を除く) は、既存の GSI を無効にします。テーブルのすべての GSI を削除して再構築するか、
UPDATE GLOBAL INDEX構文を使用して同じステートメント内で再構築する必要があります。説明GSI を無効化せずにレンジまたは LIST パーティションを削除したり、パーティションを切り捨てたりする機能は制限付き機能です。使用する前に申請が必要です。詳細については、「機能強化」をご参照ください。
機能強化
-
並列 DDL を使用して、GSI をより高速に作成できます。
-
GSI を持つパーティションテーブルでカラムの即時追加を使用できます。
-
GSI を持つレンジまたは LIST パーティションテーブルでは、新しいパーティションを追加する際にパーティションレベルのメタデータロック (MDL) がサポートされます。
-
GSI を持つテーブルを INTERVAL RANGE パーティションテーブルに変換したり、INTERVAL RANGE パーティションテーブルに直接 GSI を作成したりできます。
-
GSI を持つパーティションテーブルでパーティションレベルの DDL 操作を実行する際、
UPDATE GLOBAL INDEX構文を使用して、同じステートメント内で GSI を再構築できます。 -
既存の GSI を無効にすることなく、RANGE または LIST パーティションの削除、あるいは任意のタイプのパーティションの TRUNCATE を実行できます。これはゲート機能です。この機能を有効にするには、Quota Center に移動し、[クォータ ID] で
polardb_mysql_gsi_drop_partitionまたはpolardb_mysql_gsi_truncate_partを検索します。[アクション] 列で、[適用] をクリックして機能を有効化します。説明この機能は、PolarDB for MySQL 8.0.2、リビジョン 8.0.2.2.31 以降でのみサポートされます。
-
GSI を持つテーブルでパーティションを DROP または TRUNCATE すると、GSI を再構築しない場合、古いデータが GSI に残る可能性があります。非同期パージ機能を有効にすると、バックグラウンドスレッドが古いデータを自動的にクリーンアップします。これはゲート機能です。有効にするには、クォータセンターに移動して [クォータ ID]
polardb_mysql_gsi_async_purgeを検索し、[操作] 列で [適用] をクリックして機能を有効化します。説明この機能は、PolarDB for MySQL 8.0.2、リビジョン 8.0.2.2.35 以降でのみサポートされます。
構文
インデックスを作成する際、インデックス名の後に GLOBAL または LOCAL キーワードを追加します。
キーワードを省略した場合、デフォルトでローカルインデックスが作成されます。
-- グローバルインデックスの作成
INDEX index_name(column) GLOBAL
-- ローカルインデックスの作成
INDEX index_name(column) LOCAL
GSI の作成
テーブル作成時の GSI 作成
GLOBAL キーワードを CREATE TABLE でインデックスを定義する際に追加します。
CREATE TABLE t1(
a INT PRIMARY KEY,
b INT,
INDEX k1(b) GLOBAL
) PARTITION BY HASH(a) PARTITIONS 3;
既存テーブルへの GSI 追加
ALTER TABLE を使用してグローバルインデックスを追加するか、CREATE UNIQUE INDEX を使用してグローバルな一意性インデックスを追加します。
-- テーブルの作成
CREATE TABLE t1(
a INT PRIMARY KEY,
b INT
) PARTITION BY HASH(a) PARTITIONS 3;
-- カラム b にグローバルインデックスを追加
ALTER TABLE t1 ADD INDEX k1(b) GLOBAL;
-- カラム b にグローバルな一意性インデックスを追加
CREATE UNIQUE INDEX k2 ON t1(b) GLOBAL;
パーティション DDL 時の GSI 再構築
UPDATE GLOBAL INDEX を使用して、パーティションレベルの DDL 操作と同じステートメント内で GSI を再構築します。これにより、GSI が無効になるのを回避できます。
次の例では、GSI を持つレンジパーティションテーブルを作成し、1 つのステートメントでパーティションを削除して GSI を再構築します。
-- ステップ 1: グローバルインデックスを持つ RANGE パーティションテーブルを作成
CREATE TABLE t1(
a INT PRIMARY KEY,
b INT,
INDEX k1(b) GLOBAL
) PARTITION BY RANGE (`a`)
(PARTITION p0 VALUES LESS THAN (5) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (10) ENGINE = InnoDB);
-- ステップ 2: p1 パーティションを削除し、GSI を再構築
ALTER TABLE t1 DROP PARTITION p1 UPDATE GLOBAL INDEX;
パフォーマンス
GSI は、パーティションキーを含まない SELECT、UPDATE、DELETE クエリにおいて、ローカルインデックスよりも優れたパフォーマンスを発揮します。その優位性は、パーティション数とデータ量の増加に伴って大きくなります。
テスト設定:32 個のパーティションと 1,000,000 行を持つ 2 つの HASH パーティションテーブル (1 つはローカルインデックス、もう 1 つは GSI を使用)。
-- ローカルインデックスを持つテーブル
CREATE TABLE mytest1.big_table_1(
a INT PRIMARY KEY,
b INT,
c INT,
INDEX k1(b) LOCAL
) PARTITION BY HASH(a) PARTITIONS 32;
-- GSI を持つテーブル
CREATE TABLE mytest2.big_table_1(
a INT PRIMARY KEY,
b INT,
c INT,
INDEX k1(b) GLOBAL
) PARTITION BY HASH(a) PARTITIONS 32;
SELECT — 実行時間、クエリ条件にパーティションキーを含まない場合:

UPDATE — 実行時間、クエリ条件にパーティションキーを含まない場合:

DELETE — 実行時間、クエリ条件にパーティションキーを含まない場合:

GSI のパフォーマンス上の優位性は、データ量とパーティション数が増加するにつれて、より顕著になります。
次のステップ
-
並列 DDL — 大規模なテーブルでの GSI 作成を高速化
-
カラムの即時追加 — テーブル全体の再構築なしに、GSI を持つパーティションテーブルにカラムを追加
-
INTERVAL RANGE パーティションテーブル — GSI と互換性のある自動パーティション管理