All Products
Search
Document Center

PolarDB:Create and use GSIs

Last Updated:May 14, 2025

This topic describes how to create and use global secondary indexes (GSIs) for tables in DRDS mode.

Note

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

    image
  • Add a GSI after creating a table

    image
Note
  • 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 TABLE statement.

  • 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 Length parameter 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.

    Note

    You 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*

Note
  • 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

DROP TABLE

Yes

DROP INDEX

Yes

TRUNCATE TABLE

Yes

RENAME TABLE

Yes

ALTER TABLE RENAME

Yes

Examples

  1. 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 3
  2. Use 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

        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 = 123
        Note

        If 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` = ?)")          
      Note
      • The base table in the above SQL query is t_order, with an equality filter condition on seller_id, and the columns involved (id, order_snapshot, and seller_id) are covered by g_i_seller. Selecting the covering index g_i_seller both avoids table lookups and clearly reduces the number of table partitions to scan (seller_id is the shard key of g_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';

FAQ

Why the error message "Does not support create Global Secondary Index on single or broadcast table" is displayed when I create a GSI?

When this error is displayed, check if the data table you are operating on is a non-partitioned table or a broadcast table. GSIs cannot be created on non-partitioned tables or broadcast tables.

Non-partitioned tables and broadcast tables:

  • Non-partitioned tables:

    • DRDS mode: A non-partitioned table is created in a single database without any sharding.

    • AUTO mode: A non-partitioned table is created with the keyword SINGLE without any partitioning.

  • A broadcast table (DRDS mode) or a broadcast table (AUTO mode) refers to a table created with the keyword BROADCAST (this table has an identical copy of data on each data node).