PolarDB for MySQL は、パーティションテーブルにグローバルセカンダリインデックス (GSI) を作成することをサポートしています。GSI はパーティションテーブルを透過的にし、非パーティションテーブルのように使用できるようにします。これにより、パーティションキーによる制限が大幅に軽減されます。
GSI 機能を使用するには、Quota Center に移動します。その [Quota ID]
polardb_mysql_gsiでクォータを検索し、[アクション] 列の [適用] をクリックして機能を有効にします。GSI の詳細については、DingTalk グループに参加してサポートを受けてください。グループ ID は 24490017825 です。
背景情報
パーティションテーブル上の従来のインデックスはローカルインデックスです。ローカルインデックスは、そのテーブルと同じ方法でパーティション化され、各インデックスパーティションのデータは対応するテーブルパーティションから構築されます。したがって、ローカルインデックスは、各パーティション内でのみデータがソートされることを保証します。ローカル一意なインデックスを作成するには、インデックスフィールドにすべてのパーティションキーを含める必要があります。
パーティションテーブルにローカルインデックスしかない場合、パーティションキーの制限により、テーブルの使用が困難になることがあります。
クエリ条件にパーティションキーが含まれていない場合、クエリはテーブルのすべてのパーティションをスキャンする必要があります。これにより、大幅な読み取り増幅が発生し、パーティションの数が増えるにつれて悪化します。
クエリ結果がインデックスフィールドに基づいて特定の順序を必要とする場合、各パーティション内のデータがソートされていても、パーティション全体でデータがグローバルにソートされることは保証されません。これにより、追加のグローバルソート操作がトリガーされる可能性があります。
ローカル一意なインデックスには、すべてのパーティションキーを含める必要があります。そうしないと、すべてのパーティションにわたるグローバルな一意性制約を保証できません。
ローカルインデックスとは異なり、PolarDB for MySQL のグローバルインデックスはパーティション化されません。すべてのパーティションのデータから構築されます。したがって、グローバルインデックス内のデータは、パーティションテーブル全体でソートされます。グローバル一意なインデックスを作成するために、インデックスフィールドにすべてのパーティションキーを含める必要はありません。
前提条件
クラスターは PolarDB for MySQL 8.0.2、リビジョン 8.0.2.2.7 以降を実行している必要があります。クラスターのバージョンを確認するには、「バージョン番号のクエリ」をご参照ください。
制限事項
グローバルセカンダリインデックスは、InnoDB エンジンを使用するパーティションテーブルでのみサポートされ、ハイブリッドパーティションテーブルではサポートされません。
グローバルセカンダリインデックスは、フルテキストインデックスまたは空間インデックスにすることはできません。
グローバルセカンダリインデックスは、圧縮テーブル、一時テーブル、暗号化テーブル、または REDUNDANT もしくは COMPRESSED 行フォーマットを使用するテーブルではサポートされていません。
GSI が作成されるテーブルは、生成列をサポートしません。
新しい RANGE または LIST パーティションの追加を除き、パーティションレベルの DDL 操作は既存の GSI を無効にします。その後、テーブル上のすべての GSI を削除して再構築する必要があります。または、
UPDATE GLOBAL INDEX構文を使用してセカンダリインデックスを再構築することもできます。
機能強化
並列 DDL を使用して GSI を並列に作成できます。
GSI を持つパーティションテーブルで カラム即時追加 機能を使用できます。
GSI を持つ RANGE または LIST パーティションテーブルの場合、新しいパーティションを追加するときにパーティションレベルのメタデータロック (MDL) がサポートされます。
GSI を持つテーブルを INTERVAL RANGE パーティションテーブルに変換できます。INTERVAL RANGE パーティションテーブルに GSI を作成することもできます。
GSI を持つパーティションテーブルでパーティションレベルの DDL 操作を実行する場合、
UPDATE GLOBAL INDEX構文を使用してテーブル上の GSI を再構築できます。例:aフィールドをパーティションキーとして使用するt1という名前の RANGE パーティションテーブルを作成し、bフィールドにk1という名前のグローバルインデックスを作成します。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);t1テーブルからp1パーティションを削除し、GSI を再構築します。ALTER TABLE t1 DROP PARTITION p1 UPDATE GLOBAL INDEX;
構文
インデックスを作成するときに、インデックス名の後に LOCAL または GLOBAL キーワードを追加して、それがローカルインデックスかグローバルインデックスかを指定できます。
インデックスの作成時に GLOBAL キーワードを指定しない場合、デフォルトでローカルインデックスが作成されます。
例
aフィールドをパーティションキーとして使用するt1という名前のパーティションテーブルを作成し、bフィールドにk1という名前のグローバルインデックスを作成します。CREATE TABLE t1( a INT PRIMARY KEY, b INT, INDEX k1(b) GLOBAL ) PARTITION BY HASH(a) PARTITIONS 3;aフィールドをパーティションキーとして使用するt1という名前のパーティションテーブルを作成し、その後t1テーブルのbフィールドにk1という名前のグローバルインデックスとk2という名前のグローバル一意なインデックスを作成できます。CREATE TABLE t1( a INT PRIMARY KEY, b INT ) PARTITION BY HASH(a) PARTITIONS 3; ALTER TABLE t1 ADD INDEX k1(b) GLOBAL; CREATE UNIQUE INDEX k2 ON t1(b) GLOBAL;
パフォーマンス テスト
テストオブジェクト
このテストでは、同じテーブルスキーマとそれぞれ 100 万のデータエントリを持つ 2 つのパーティションテーブルを使用します。一方のパーティションテーブルにはローカルインデックスが作成され、もう一方には GSI が作成されます。
この例では、パーティションテーブル mytest1.big_table_1 と mytest2.big_table_1 を使用します。mytest1.big_table_1 テーブルにはローカルインデックスがあり、mytest2.big_table_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;
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 のパフォーマンスを比較します。
テスト結果
パーティションキーを含まないクエリ条件を持つ SELECT 文の実行時間。

パーティションキーを含まないクエリ条件を持つ UPDATE 文の実行時間。

パーティションキーを含まないクエリ条件を持つ DELETE 文の実行時間。

テスト結果は、クエリ条件にパーティションキーが含まれていない場合、SELECT、UPDATE、および DELETE コマンドが GSI を使用するとより高速に実行されることを示しています。このパフォーマンス上の利点は、データ量が増加するにつれてより顕著になります。