PolarDB-X 1.0 の既存テーブルにローカルセカンダリインデックス (LSI) またはグローバルセカンダリインデックス (GSI) を追加するには、CREATE INDEX を使用します。
LSI
LSI の構文は、標準の MySQL CREATE INDEX 文に従います。完全な構文リファレンスについては、「MySQL CREATE INDEX」をご参照ください。
GSI
GSI はすべてのデータベースシャードにまたがり、クエリがシャードキー以外の列でフィルターをかける際に全シャードをスキャンせずに済みます。プライマリテーブルのシャードキー以外の列でフィルターをかける必要があるクエリでは、GSI を使用してください。
構文
CREATE [UNIQUE]
GLOBAL INDEX index_name [index_type]
ON tbl_name (index_sharding_col_name, ...)
global_secondary_index_option
[index_option]
[algorithm_option | lock_option] ...
-- GSI 固有のオプション
global_secondary_index_option:
[COVERING (col_name, ...)]
drds_partition_options
-- インデックステーブルのシャーディングオプション
drds_partition_options:
DBPARTITION BY db_sharding_algorithm
[TBPARTITION BY table_sharding_algorithm [TBPARTITIONS num]]
db_sharding_algorithm:
HASH([col_name])
| {YYYYMM | YYYYWEEK | YYYYDD | YYYYMM_OPT | YYYYWEEK_OPT | YYYYDD_OPT}(col_name)
| UNI_HASH(col_name)
| RIGHT_SHIFT(col_name, n)
| RANGE_HASH(col_name, col_name, n)
table_sharding_algorithm:
HASH(col_name)
| {MM | DD | WEEK | MMDD | YYYYMM | YYYYWEEK | YYYYDD | YYYYMM_OPT | YYYYWEEK_OPT | YYYYDD_OPT}(col_name)
| UNI_HASH(col_name)
| RIGHT_SHIFT(col_name, n)
| RANGE_HASH(col_name, col_name, n)
-- length パラメーターは、インデックステーブルのシャードキー上に LSI を作成する場合にのみ適用されます
index_sharding_col_name:
col_name [(length)] [ASC | DESC]
index_option:
KEY_BLOCK_SIZE [=] value
| index_type
| WITH PARSER parser_name
| COMMENT 'string'
index_type:
USING {BTREE | HASH}
algorithm_option:
ALGORITHM [=] {DEFAULT | INPLACE | COPY}
lock_option:
LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}パラメーター
| パラメーター | 説明 |
|---|---|
UNIQUE | すべてのシャードにわたってグローバルな一意制約を適用します。PolarDB-X は、この制約を維持するために、GSI インデックス列すべてをカバーするローカルの一意なインデックスをインデックステーブルに自動的に作成します。 |
GLOBAL | インデックスを GSI として指定するための必須キーワードです。GLOBAL を指定しない場合、CREATE INDEX は標準の MySQL ローカルインデックスを作成します。 |
index_name | インデックス名です。テーブル内で一意である必要があります。 |
index_sharding_col_name | インデックステーブルのシャードキー列です。インデックステーブル内のデータがシャード間でどのように分散されるかを決定します。 |
COVERING (col_name, ...) | インデックステーブルに格納する追加の列です。クエリが GSI のシャードキーでフィルターをかけ、かつカバーリング対象の列のみを選択する場合、PolarDB-X はプライマリテーブルへの結合を行わずに直接インデックステーブルから読み取ります。この句を指定しない場合、プライマリキーおよびプライマリテーブルのシャードキーのみがデフォルトのカバーリング列として格納され、それ以外の列を選択するクエリはプライマリテーブルへの結合が必要になります。 |
DBPARTITION BY | 必須です。インデックステーブルのデータベースレベルのシャーディングアルゴリズムを指定します。 |
TBPARTITION BY | 任意です。テーブルレベルのシャーディングアルゴリズムとテーブルシャード数 (TBPARTITIONS) を指定します。 |
前提条件
注: GSI を含むテーブルに対して ALTER TABLE を実行するには、MySQL のバージョンが 5.7 以降であり、かつ PolarDB-X 1.0 のバージョンが V5.4.1 以降である必要があります。GSI の制限事項の完全なリストについては、「GSI の使用に関する注意事項」をご参照ください。
GSI の定義に使用される句の詳細については、「CREATE TABLE」をご参照ください。
例:テーブル作成後に GSI を作成する
以下の例では、order_id でシャーディングされた既存の t_order テーブルの buyer_id 列に GSI を作成します。
手順 1:プライマリテーブルを作成します。
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`),
KEY `l_i_order` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by hash(`order_id`);プライマリテーブル t_order は、order_id に対するハッシュシャーディングを使用してデータベースシャードに分割されています。テーブルシャードは存在しません。
手順 2:GSI を追加します。
ALTER TABLE t_order
ADD UNIQUE GLOBAL INDEX `g_i_buyer` (`buyer_id`)
COVERING (`order_snapshot`)
dbpartition by hash(`buyer_id`);これにより、buyer_id 上に g_i_buyer という名前の一意な GSI が作成されます。インデックステーブルは buyer_id でシャーディングされます。order_snapshot がカバーリング列として指定されているため、buyer_id でフィルターをかけ、かつ order_snapshot を選択するクエリは、t_order への結合を行わずに直接インデックステーブルから読み取ります。デフォルトのカバーリング列であるプライマリキーの id およびプライマリテーブルのシャードキーである order_id は自動的に追加されます。
手順 3:インデックスを確認します。
SHOW INDEX を実行すると、order_id 上の LSI および buyer_id 上の GSI を含むすべてのインデックスが表示されます。
mysql> SHOW INDEX FROM t_order;+---------+------------+-----------+--------------+----------------+-----------+-------------+----------+--------+------+------------+----------+---------------+
| TABLE | NON_UNIQUE | KEY_NAME | SEQ_IN_INDEX | COLUMN_NAME | COLLATION | CARDINALITY | SUB_PART | PACKED | NULL | INDEX_TYPE | COMMENT | INDEX_COMMENT |
+---------+------------+-----------+--------------+----------------+-----------+-------------+----------+--------+------+------------+----------+---------------+
| t_order | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| t_order | 1 | l_i_order | 1 | order_id | A | 0 | NULL | NULL | YES | BTREE | | |
| t_order | 0 | g_i_buyer | 1 | buyer_id | NULL | 0 | NULL | NULL | YES | GLOBAL | INDEX | |
| t_order | 1 | g_i_buyer | 2 | id | NULL | 0 | NULL | NULL | | GLOBAL | COVERING | |
| t_order | 1 | g_i_buyer | 3 | order_id | NULL | 0 | NULL | NULL | YES | GLOBAL | COVERING | |
| t_order | 1 | g_i_buyer | 4 | order_snapshot | NULL | 0 | NULL | NULL | YES | GLOBAL | COVERING | |
+---------+------------+-----------+--------------+----------------+-----------+-------------+----------+--------+------+------------+----------+---------------+出力には、インデックスキー列(buyer_id)の INDEX_TYPE が GLOBAL、カバリング列(id、order_id、および order_snapshot)の INDEX_TYPE が GLOBAL COVERING である g_i_buyer が表示されます。
GSI 固有の詳細(シャーディングポリシーやステータスなど)のみを表示するには、SHOW GLOBAL INDEX を実行します。
mysql> SHOW GLOBAL INDEX FROM t_order;+---------------------+---------+------------+-----------+-------------+------------------------------+------------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+--------+
| SCHEMA | TABLE | NON_UNIQUE | KEY_NAME | INDEX_NAMES | COVERING_NAMES | INDEX_TYPE | DB_PARTITION_KEY | DB_PARTITION_POLICY | DB_PARTITION_COUNT | TB_PARTITION_KEY | TB_PARTITION_POLICY | TB_PARTITION_COUNT | STATUS |
+---------------------+---------+------------+-----------+-------------+------------------------------+------------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+--------+
| ZZY3_DRDS_LOCAL_APP | t_order | 0 | g_i_buyer | buyer_id | id, order_id, order_snapshot | NULL | buyer_id | HASH | 4 | | NULL | NULL | PUBLIC |
+---------------------+---------+------------+-----------+-------------+------------------------------+------------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+--------+インデックステーブルのスキーマを確認するには、インデックステーブルに対して SHOW CREATE TABLE を実行します。
mysql> SHOW CREATE TABLE g_i_buyer;+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| g_i_buyer | CREATE TABLE `g_i_buyer` (
`id` bigint(11) NOT NULL,
`order_id` varchar(20) DEFAULT NULL,
`buyer_id` varchar(20) DEFAULT NULL,
`order_snapshot` longtext,
PRIMARY KEY (`id`),
UNIQUE KEY `auto_shard_key_buyer_id` (`buyer_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by hash(`buyer_id`) |
+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+インデックステーブルには、プライマリテーブルのプライマリキー、データベースシャードキーおよびテーブルシャードキー、デフォルトのカバーリング列、およびカスタムのカバーリング列が含まれています。プライマリテーブルとは以下の点で異なります。
プライマリキー列 (
id) からAUTO_INCREMENTが削除されています。プライマリテーブルの LSI (
l_i_order) は存在しません。グローバルな一意制約を適用するために、
buyer_id上にローカルの一意なインデックス (auto_shard_key_buyer_id) が自動的に作成されています。