This topic describes how to create and use global secondary indexes (GSIs) for tables in DRDS mode.
The methods in this topic also apply to tables in AUTO mode. However, you must use the syntax described in CREATE INDEX (AUTO mode).
GSI syntax structure
PolarDB-X extends the MySQL DDL syntax to support creating GSIs, which is the same as creating indexes in MySQL.
Define a GSI when creating a table
Add a GSI after creating a table
Index name: The name of the GSI.
Base table name: The host table of the GSI.
Index column: The shard key of the GSI, which includes all columns used in the index sharding clause.
Covering column: Other columns in the GSI. By default, this includes the primary key and all shard keys of the base table.
Sharding clause: The database and table sharding algorithm of the GSI. The syntax is consistent with the sharding clause in the
CREATE TABLEstatement.The preceding variables are for creating a GSI in a table in DRDS mode. For more information about creating a GSI in a table in AUTO mode, see CREATE TABLE (AUTO mode).
Constraints
Constraints on creating GSIs
You cannot create a global secondary index for a non-partitioned table or for a broadcast table.
Unique global secondary indexes do not support prefix indexes.
When you create an index table, you must specify a name for the index.
When you create an index table, you must specify a database sharding rule or a rule for database sharding and table sharding. Note that you cannot specify only a table sharding rule.
The index keys of an index table must include all shard keys of the index table.
You cannot specify the same column as an index key column and a covering column.
By default, an index table contains the primary key columns and all shard key columns of the base table. If you do not specify the columns of the primary key and shard keys as index key columns, these columns are used as covering columns by default.
In DRDS mode databases, if all index columns of a local index in the base table are included in the index table, the local index is added to the index table by default.
If no local indexes are created on the index key columns of a global secondary index, a local index is automatically created on each index key column of the global secondary index.
By default, a composite index is created for a global secondary index that is created on multiple columns. The composite index applies to all index key columns of the global secondary index.
The
Lengthparameter can be used to specify only the length of a sharding key prefix that you want to use to create a local index.When you create a global secondary index for a table, the system verifies the data after the global secondary index is created. The DDL statement that is used to create the global secondary index can be executed only after the data in the index table is verified.
NoteYou can also use CHECK GLOBAL INDEX statement to verify and correct the data in an index table.
Constraints on ALTER TABLE
Clause | Change shard keys of the base table | Change the primary key | Change the unique column of a local index | Change shard keys of the index table | Change columns in the unique index of the table | Change index columns | Change covering columns |
ADD COLUMN | N/A | Not supported | N/A | N/A | N/A | N/A | N/A |
ALTER COLUMN SET DEFAULT and ALTER COLUMN DROP DEFAULT | Supported | Supported | Supported | Supported | Supported | Supported | Supported |
CHANGE COLUMN | Not supported | Not supported | Supported | Not supported | Supported* | Supported* | Supported* |
DROP COLUMN | Not supported | Not supported | Supported only if the unique index is created only on one column | Not supported | Supported* | Supported* | Supported* |
MODIFY COLUMN | Supported* (only in AUTO mode) | Supported* | Supported | Supported* (only in AUTO mode) | Supported* | Supported* | Supported* |
Supported*: indicates that only instances that meet the conditions for supporting lock-free column type changes are supported.
The DROP COLUMN statement cannot be used to rename a global secondary index. If you rename a global secondary index, the performance of the global secondary index may be affected in a negative manner. If you want to delete columns in a global secondary index, you can use the DROP INDEX statement to delete the global secondary index and then create a new global secondary index. You can also contact us for technical support.
In specific scenarios, the same column belongs to different column types that are described in the preceding table. For example, the same shard key column of a table is used as an index column and a covering column. When the same column is used as columns of different types in an index table and an operation is not supported by one of the column types, you cannot perform the operation on the column.
The following table describes the ALTER TABLE statements that you can use to manage indexes.
Statement | Description |
ALTER TABLE ADD PRIMARY KEY | Supported. |
ALTER TABLE ADD [UNIQUE/FULLTEXT/SPATIAL/FOREIGN] KEY | Supported. You can use this statement to add a local index on the base table and the index table at the same time. The name of the local index cannot be the same as the name of the global secondary index. |
ALTER TABLE ALTER INDEX index_name {VISIBLE | INVISIBLE} | Supported. You can use this statement only on the base table. You cannot use this statement to change the status of a global secondary index. |
ALTER TABLE {DISABLE | ENABLE} KEYS | Supported. You can use this statement only on the base table. You cannot use this statement to change the status of a global secondary index. |
ALTER TABLE DROP PRIMARY KEY | Not supported. |
ALTER TABLE DROP INDEX | Supported. You can use this statement to delete only a common index or a global secondary index. |
ALTER TABLE DROP FOREIGN KEY fk_symbol | Supported. You can execute this statement only on the base table. |
ALTER TABLE RENAME INDEX | Supported. |
Constraints on ALTER GSI TABLE
DDL and DML statements cannot be executed on GSIs.
DML statements with NODE HINTs cannot update the base table and GSIs.
Other constraints
Statement | Supported in tables with GSIs |
Yes | |
Yes | |
Yes | |
Yes | |
ALTER TABLE RENAME | Yes |
Examples
Create a GSI.
-- Define a GSI when creating a table 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`); -- Add a 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 3Use the GSI in queries.
Specify an index using a hint
You can choose either of the following two HINT statements to specify the target index for the query.
FORCE INDEX({index_name})Example:
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})*/Example:
/*+TDDL:index(a, g_i_buyer)*/ SELECT * FROM t_order a WHERE a.buyer_id = 123NoteIf a query needs to use columns not included in the index, the GSI is first queried to obtain the primary keys and base table shard keys of all records, and then the base table is queried to obtain the values of the missing columns. For more information, see INDEX HINT.
Index selection examples:
For queries on a base table with GSIs, PolarDB-X automatically selects the GSI that the optimizer considers to have the lowest cost (only covering index selection is supported).
EXPLAIN SELECT t_order.id,t_order.order_snapshot FROM t_order WHERE t_order.seller_id = 's1';Execution plan result:
IndexScan(tables="g_i_seller_sfL1_2", sql="SELECT `id`, `order_snapshot` FROM `g_i_seller` AS `g_i_seller` WHERE (`seller_id` = ?)")NoteThe base table in the above SQL query is
t_order, with an equality filter condition onseller_id, and the columns involved (id,order_snapshot, andseller_id) are covered byg_i_seller. Selecting the covering indexg_i_sellerboth avoids table lookups and clearly reduces the number of table partitions to scan (seller_idis the shard key ofg_i_seller).In the execution plan result, you can see that the PolarDB-X optimizer has selected
g_i_seller.
IGNORE INDEX
Syntax:
IGNORE INDEX({index_name},...)Example:
SELECT t_order.id,t_order.order_snapshot FROM t_order IGNORE INDEX(g_i_seller) WHERE t_order.seller_id = 's1';USE INDEX
Syntax:
USE INDEX({index_name},...)Example:
SELECT t_order.id,t_order.order_snapshot FROM t_order USE INDEX(g_i_seller) WHERE t_order.seller_id = 's1';