このトピックでは、DRDS モードのテーブルのグローバルセカンダリインデックス (GSI) を作成および使用する方法について説明します。
このトピックのメソッドは、AUTO モードのテーブルにも適用されます。ただし、「CREATE INDEX (AUTO モード)」で説明されている構文を使用する必要があります。
GSI 構文構造
PolarDB-X は MySQL DDL 構文を拡張して GSI の作成をサポートしています。これは MySQL でのインデックスの作成と同じです。
テーブルの作成時に GSI を定義する
テーブルの作成後に GSI を追加する
インデックス名:GSI の名前。
ベーステーブル名:GSI のホストテーブル。
インデックス列:GSI のシャードキー。インデックスシャーディング句で使用されるすべての列が含まれます。
カバリング列:GSI のその他の列。デフォルトでは、プライマリキーとプライマリテーブルのすべてのシャードキーが含まれます。
シャーディング句:GSI のデータベースおよびテーブルシャーディングアルゴリズム。構文は
CREATE TABLE
文のシャーディング句と一致します。DRDS モードのテーブルに GSI を作成するための前述の変数。AUTO モードのテーブルに GSI を作成する方法の詳細については、「CREATE TABLE (AUTO モード)」をご参照ください。
制約
GSI 作成の制約
GSI は、単一テーブルまたはブロードキャストテーブルには作成できません。
プレフィックスインデックスは、UNIQUE GSI では使用できません。
GSI を作成するときは、インデックス名を指定する必要があります。
GSI を作成するときは、データベースシャーディングルール、またはデータベースとテーブルシャーディングルールの組み合わせを指定する必要があります。テーブルシャーディングルールのみ、またはシャーディングルールなしを指定することはできません。
GSI のインデックス列には、すべてのシャードキーを含める必要があります。
GSI 定義句では、インデックス列とカバリング列を重複させることはできません。
GSI には、デフォルトでプライマリテーブルのすべてのプライマリキーとシャードキーが含まれます。インデックス列に明示的に含まれていない場合は、デフォルトでカバリング列に追加されます。
DRDS モードデータベースでは、プライマリテーブルの各ローカルインデックスについて、参照されるすべての列が GSI に含まれている場合、ローカルインデックスはデフォルトで GSI に追加されます。
GSI の各インデックス列について、インデックスがまだ存在しない場合は、デフォルトで個別のインデックスが作成されます。
複数のインデックス列を持つ GSI の場合、すべてのインデックス列を含む結合ローカルインデックスがデフォルトで作成されます。
インデックス定義では、インデックス列の
Length
パラメーターは、GSI シャードキーにローカルインデックスを作成するためにのみ使用されます。テーブルを作成した後に GSI を作成する場合、GSI 作成の最後にデータ検証が自動的に実行されます。GSI を作成するための DDL 文は、検証に合格した場合にのみ成功します。
説明また、「CHECK GLOBAL INDEX」を使用して、インデックスデータを確認または修正することもできます。
ALTER TABLE の制約
句 | ベーステーブルのシャードキーを変更する | プライマリキーを変更する | ローカルインデックスの一意な列を変更する | インデックステーブルのシャードキーを変更する | テーブルの一意なインデックスの列を変更する | インデックス列を変更する | カバリング列を変更する |
ADD COLUMN | 該当なし | サポートされていません | 該当なし | 該当なし | 該当なし | 該当なし | 該当なし |
ALTER COLUMN SET DEFAULT and ALTER COLUMN DROP DEFAULT | サポートされています | サポートされています | サポートされています | サポートされています | サポートされています | サポートされています | サポートされています |
CHANGE COLUMN | サポートされていません | サポートされていません | サポートされています | サポートされていません | サポートされています* | サポートされています* | サポートされています* |
DROP COLUMN | サポートされていません | サポートされていません | 一意なインデックスが 1 つの列のみに作成されている場合にのみサポートされます | サポートされていません | サポートされています* | サポートされています* | サポートされています* |
MODIFY COLUMN | サポートされています* (AUTO モードのみ) | サポートされています* | サポートされています | サポートされています* (AUTO モードのみ) | サポートされています* | サポートされています* | サポートされています* |
サポートされています*:ロックフリーの列タイプ変更をサポートするための条件を満たすインスタンスのみがサポートされていることを示します。
グローバルセカンダリインデックスの安定性とパフォーマンスを考慮して、DROP COLUMN コマンドを直接使用してグローバルセカンダリインデックスの列を削除することは現在禁止されています。グローバルセカンダリインデックスの特定の列を削除する必要がある場合は、最初に DROP INDEX を使用して対応するグローバルセカンダリインデックスを削除してから、新しいセカンダリインデックスを作成するか、お問い合わせ いただき、テクニカルサポートを受けてください。
上記の列分類は重複しています (たとえば、インデックス列にはグローバルセカンダリインデックスシャードキーが含まれ、カバリング列にはプライマリテーブルシャードキー、プライマリキー、および指定された列が含まれます)。サポート状況が競合する場合は、「サポートされていません」が「サポートされています」よりも優先されます。
次の表は、インデックスの管理に使用できる ALTER TABLE
文を示しています。
文 | 説明 |
ALTER TABLE ADD PRIMARY KEY | サポートされています。 |
ALTER TABLE ADD [UNIQUE/FULLTEXT/SPATIAL/FOREIGN] KEY | サポートされています。この文を使用して、ベーステーブルとインデックステーブルに同時にローカルインデックスを追加できます。ローカルインデックスの名前は、GSI の名前と同じにすることはできません。 |
ALTER TABLE ALTER INDEX index_name {VISIBLE | INVISIBLE} | サポートされています。GSI ステータスを変更するのではなく、ベーステーブルでのみ使用できます。 |
ALTER TABLE {DISABLE | ENABLE} KEYS | サポートされています。GSI ステータスを変更するのではなく、ベーステーブルでのみ使用できます。 |
ALTER TABLE DROP PRIMARY KEY | サポートされていません。 |
ALTER TABLE DROP INDEX | サポートされています。標準インデックスまたは GSI を削除するためにのみ使用できます。 |
ALTER TABLE DROP FOREIGN KEY fk_symbol | サポートされています。ベーステーブルでのみ使用できます。 |
ALTER TABLE RENAME INDEX | サポートされています。 |
ALTER GSI TABLE の制約
DDL 文と DML 文は、GSI では実行できません。
NODE HINT を含む DML 文は、ベーステーブルと GSI を更新できません。
その他の制約
文 | GSI を含むテーブルでサポートされています |
はい | |
はい | |
はい | |
はい | |
ALTER TABLE RENAME | はい |
例
GSI を作成します。
-- テーブルの作成時に GSI を定義する CREATE TABLE t_order ( `id` BIGINT(11) NOT NULL AUTO_INCREMENT, `order_id` VARCHAR(20) DEFAULT NULL, `buyer_id` VARCHAR(20) DEFAULT NULL, `seller_id` VARCHAR(20) DEFAULT NULL, `order_snapshot` LONGTEXT DEFAULT NULL, `order_detail` LONGTEXT DEFAULT NULL, PRIMARY KEY (`id`), GLOBAL INDEX `g_i_seller`(`seller_id`) COVERING (`id`, `order_id`, `buyer_id`, `order_snapshot`) dbpartition BY hash(`seller_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition BY hash(`order_id`); -- GSI を追加する CREATE UNIQUE GLOBAL INDEX `g_i_buyer` ON `t_order`(`buyer_id`) COVERING(`seller_id`, `order_snapshot`) dbpartition BY hash(`buyer_id`) tbpartition BY hash(`buyer_id`) tbpartitions 3
クエリで GSI を使用します。
HINT を使用してインデックスを指定する
次の 2 つの HINT 文のいずれかを選択して、クエリのターゲットインデックスを指定できます。
FORCE INDEX({index_name})
例:
SELECT a.order_id FROM t_order a FORCE INDEX(g_i_seller) WHERE a.buyer_id = 123;
HINT
/*+TDDL:INDEX({table_name/table_alias}, {index_name})*/
例:
/*+TDDL:index(a, g_i_buyer)*/ SELECT * FROM t_order a WHERE a.buyer_id = 123
説明クエリでインデックスに含まれていない列を使用する必要がある場合、最初に GSI にクエリを実行してすべてのレコードのプライマリキーとプライマリテーブルシャードキーを取得し、次にプライマリテーブルにクエリを実行して不足している列の値を取得します。詳細については、「INDEX HINT」をご参照ください。
インデックス選択クエリの例:
GSI を持つプライマリテーブルに対するクエリの場合、PolarDB-X は、オプティマイザーが最もコストが低いと考える GSI を自動的に選択します (カバリングインデックスの選択のみがサポートされています)。
EXPLAIN SELECT t_order.id,t_order.order_snapshot FROM t_order WHERE t_order.seller_id = 's1';
実行計画の結果:
IndexScan(tables="g_i_seller_sfL1_2", sql="SELECT `id`, `order_snapshot` FROM `g_i_seller` AS `g_i_seller` WHERE (`seller_id` = ?)")
説明上記の SQL クエリにおけるプライマリテーブルは
t_order
で、seller_id
に等価フィルター条件があり、関連する列 (id
、order_snapshot
、およびseller_id
) はg_i_seller
でカバーされています。カバリングインデックスg_i_seller
を選択すると、テーブルルックアップが回避され、スキャンするテーブルパーティションの数が明確に削減されます (seller_id
はg_i_seller
のシャードキーです)。実行計画の結果では、PolarDB-X オプティマイザーが
g_i_seller
を選択したことがわかります。
IGNORE INDEX
構文:
IGNORE INDEX({index_name},...)
例:
SELECT t_order.id,t_order.order_snapshot FROM t_order IGNORE INDEX(g_i_seller) WHERE t_order.seller_id = 's1';
USE INDEX
構文:
USE INDEX({index_name},...)
例:
SELECT t_order.id,t_order.order_snapshot FROM t_order USE INDEX(g_i_seller) WHERE t_order.seller_id = 's1';