This topic explains how to create and use the clustered columnar index (CCI) feature in PolarDB-X to accelerate analytical queries on your data..
Prerequisites
Your instance must meet the following requirements to use the CCI feature:
Instance edition: Enterprise Edition with an
AUTOmode database.Instance version: 5.4.19-16989811 or higher.
For information about the instance version naming rules, see Release notes.
For information about how to view the version of an instance, see View and update the version of an instance.
Precautions
The following constraints apply when you create a CCI:
Prefix indexes cannot be used.
You must specify an index name when you create a CCI.
By default, a CCI includes all columns of the primary table. After the CCI is created, it is automatically adjusted based on column changes in the primary table. You cannot manually adjust the columns.
Creating a CCI does not create any additional local indexes.
In an index definition, the
LENGTHparameter of the sort key is ignored.
Primary instances, read-only instances, and columnstore read-only instances support query commands such as
SHOW INDEX. For more information, see SHOW COLUMNAR INDEX, SHOW COLUMNAR OFFSET, and SHOW COLUMNAR STATUS.For more information about DDL-related limits, see Limits.
Syntax
PolarDB-X extends the syntax of Data Definition Language (DDL) statements in MySQL. The following syntax is added to define a CCI. You can use this syntax in the same way that you create an index in MySQL.
CREATE
CLUSTERED COLUMNAR INDEX index_name
ON tbl_name (index_sort_key_name,...)
[partition_options]
# Define a partitioning policy
partition_options:
PARTITION BY
HASH({column_name | partition_func(column_name)})
| KEY(column_list)
| RANGE({column_name | partition_func(column_name)})
| RANGE COLUMNS(column_list)
| LIST({column_name | partition_func(column_name)})
| LIST COLUMNS(column_list)} }
partition_list_spec
# Define a partitioning function
partition_func:
YEAR
| TO_DAYS
| TO_SECOND
| UNIX_TIMESTAMP
| MONTH
# Define a partition list
partition_list_spec:
hash_partition_list
| range_partition_list
| list_partition_list
# Define columns for a HASH/KEY partitioned table
hash_partition_list:
PARTITIONS partition_count
# Define columns for a RANGE/RANGE COLUMNS partitioned table
range_partition_list:
range_partition [, range_partition ...]
range_partition:
PARTITION partition_name VALUES LESS THAN {(expr | value_list)} [partition_spec_options]
# Define columns for a LIST/LIST COLUMNS partitioned table
list_partition_list:
list_partition [, list_partition ...]
list_partition:
PARTITION partition_name VALUES IN (value_list) [partition_spec_options]Example
Execute the following statements to create a table named t_order, and a CCI named cc_i_seller on the t_order 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`),
KEY `l_i_order` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 partition by hash(`order_id`) partitions 16;CREATE CLUSTERED COLUMNAR INDEX `cc_i_seller` ON t_order (`seller_id`) partition by hash(`order_id`) partitions 16;The following section describes the CCI creation code in detail:
CLUSTERED COLUMNAR: A keyword that specifies that the type of the index to be added is a CCI.
Primary table:
t_orderis a partitioned table that uses HASH partitioning on theorder_idcolumn.Index name: The name of the index, which is used to specify the index in SQL statements.
Sort key: The sort key of the index. Data in the index file is stored in order based on this column.
Index partition clause: The partitioning algorithm for the index. The syntax of this clause is the same as the syntax of the partition clause in the
CREATE TABLEstatement. In this clause,order_idis the hash column.Index definition clause:
CLUSTERED COLUMNAR INDEX `cc_i_seller` ON t_order (`seller_id`) partition by hash(`order_id`) partitions 16.
How to use a CCI in queries
After you create a CCI, you can specify the index table to use for queries in the following ways:
Specify an index using a hint
Syntax:
FORCE INDEX({index_name})Example:
SELECT a.*, b.order_id
FROM t_seller a
JOIN t_order b FORCE INDEX(cc_i_seller) ON a.seller_id = b.seller_id
WHERE a.seller_nick="abc";Index selection method
For queries on a primary table that contains a CCI, PolarDB-X automatically selects the index table that the optimizer determines has the lowest cost. Currently, only columnstore read-only instances support CCI-based queries.
Do not use a specified index (IGNORE INDEX)
Syntax:
IGNORE INDEX({index_name},...)The following statement specifies that the optimizer does not use the cc_i_seller index:
SELECT t_order.id,t_order.order_snapshot FROM t_order IGNORE INDEX(cc_i_seller) WHERE t_order.seller_id = 's1';Use a specified index (USE INDEX)
Syntax:
USE INDEX({index_name},...)The following statement specifies that the optimizer uses the cc_i_seller index:
SELECT t_order.id,t_order.order_snapshot FROM t_order USE INDEX(cc_i_seller) WHERE t_order.seller_id = 's1';Limits
The limits are classified into the following three types:
When you create a CCI, the data types of the primary key, sort key, and partition key are subject to certain limits.
When you execute DDL statements on a table that contains a CCI, certain limits apply. Currently, only common DDL statements are supported.
When you execute a DDL statement to change the data type of a column, only a limited number of data types are supported.
Supported data types
The following table shows the supported data types for the primary key of the primary table, as well as the sort and partition keys of the CCI:
Data type | Primary key | Sort key | Partition key | |
Numeric types | BIT (UNSIGNED) | Supported | Supported | Not supported |
TINYINT (UNSIGNED) | Supported | Supported | Supported | |
SMALLINT (UNSIGNED) | Supported | Supported | Supported | |
MEDIUMINT (UNSIGNED) | Supported | Supported | Supported | |
INT (UNSIGNED) | Supported | Supported | Supported | |
BIGINT (UNSIGNED) | Supported | Supported | Supported | |
Time types | DATE | Supported | Supported | Supported |
DATETIME | Supported | Supported | Supported | |
TIMESTAMP | Supported | Supported | Supported | |
TIME | Supported | Supported | Not supported | |
YEAR | Supported | Supported | Not supported | |
String types | CHAR | Supported | Supported | Supported |
VARCHAR | Supported | Supported | Supported | |
TEXT | Supported | Supported | Not supported | |
BINARY | Supported | Supported | Supported | |
VARBINARY | Supported | Supported | Supported | |
BLOB | Supported | Supported | Not supported | |
Floating-point number types | FLOAT | Not supported | Not supported | Not supported |
DOUBLE | Not supported | Not supported | Not supported | |
DECIMAL | Not supported | Not supported | Not supported | |
NUMERIC | Not supported | Not supported | Not supported | |
Special types | JSON | Not supported | Not supported | Not supported |
ENUM | Not supported | Not supported | Not supported | |
SET | Not supported | Not supported | Not supported | |
POINT | Not supported | Not supported | Not supported | |
GEOMETRY | Not supported | Not supported | Not supported | |
Partitioning algorithms support different data types. For more information, see Data types.
Limits on DDL statements
You can control whether to allow DDL statements to be executed on a table with a CCI (true: allowed, false: not allowed) using the following statement:
SET [GLOBAL] forbid_ddl_with_cci = [true | false];The following table describes the DDL support for primary tables that contain CCIs and for CCIs.
Category
Action
Sample SQL
Supported
Primary table
Delete table
DROP TABLE tbl_name;Yes
Truncate table
TRUNCATE TABLE tbl_name;Yes
Rename table
ALTER TABLE old_tbl_name RENAME TO new_tbl_name;RENAME TABLE old_tbl_name TO new_tbl_name;
Yes
Rename multiple tables
RENAME TABLE tbl_name_a to tbl_name_b, tbl_name_c to tbl_name_d;Yes
Add column
ALTER TABLE tbl_name ADD col_name TYPE;Yes
Delete column
ALTER TABLE tbl_name DROP COLUMN col_name;Yes
Modify column type
ALTER TABLE tbl_name MODIFY col_name TYPE;Yes
Rename (modify) column
ALTER TABLE tbl_name CHANGE old_col new_col TYPE;Yes
Modify column default value
ALTER TABLE tbl_name ALTER COLUMN col_name SET DEFAULT default_value;ALTER TABLE tbl_name ALTER COLUMN col_name DROP DEFAULT;
Yes
Lock-free column type change
ALTER TABLE tbl_name MODIFY col_name TYPE, ALGORITHM = omc;Yes
Multiple
ALTER TABLEoperationsALTER TABLE tbl_name MODIFY col_name_a, DROP COLUMN col_name_b;Yes
Generated column
-
No
Partition change
-
No
CCI
Create CCI
CREATE CLUSTERED COLUMNAR INDEX cci_name;ALTER TABLE tbl_name ADD CLUSTERED COLUMNAR INDEX cci_name;
Yes
Delete CCI
DROP INDEX cci_name ON TABLE tbl_name;ALTER TABLE tbl_name DROP INDEX cci_name;
Yes
Change CCI name
ALTER TABLE tbl_name RENAME INDEX cci_name_a TO cci_name_b;Yes
Add a RANGE partition to a CCI
ALTER TABLE `tbl_name`.`cci_name` ADD PARTITION;Yes
Other CCI partition changes
-
No
The following constraints apply when you use
ALTER TABLEto change columns:Statement
Can the primary key be changed?
Can the index partition key be changed?
Can the sort key be changed?
MODIFY COLUMN
Yes
Yes
Yes
ALTER COLUMN SET DEFAULT, ALTER COLUMN DROP DEFAULT
Yes
Yes
Yes
ADD COLUMN
No
N/A
N/A
CHANGE COLUMN
No
No
No
DROP COLUMN
No
No
No
NoteCurrently, you can execute ALTER TABLE statements related to column changes on tables that contain a CCI.
In versions 5.4.20-20250714 and later, MODIFY COLUMN and changing column default values are supported for modifying some primary keys, CCI partition keys, and CCI sort keys.
Modifying a critical column (primary key, CCI partition key, or CCI sort key) may trigger a full rebuild of the CCI. This can be a long-running operation on large tables. This is disabled by default. We recommend that you use asynchronous execution. To use this feature, set the following parameters:
# Allow modifying critical columns of a CCI SET ENABLE_MODIFY_CCI_CRITICAL_COLUMN = TRUE; # The rebuild logic for critical columns. 0 indicates that the system automatically selects a logic based on the policy. We recommend that you do not change this value. SET REBUILD_CCI_STRATEGY = 0; # The maximum number of CCIs allowed in a table. If multiple CCIs already exist in the table, you can set this value to a larger number. SET MAX_CCI_COUNT = 2;
The following table describes the supported data type for the
MODIFY/CHANGE COLUMNstatement:Supported types
Unsupported types
Numeric types: BIT (UNSIGNED), TINYINT (UNSIGNED), SMALLINT (UNSIGNED), MEDIUMINT (UNSIGNED), INT (UNSIGNED), and BIGINT (UNSIGNED)
Time types: DATETIME, TIMESTAMP, TIME, and YEAR
Floating-point number types: FLOAT, DOUBLE, DECIMAL, and NUMERIC
String types: CHAR, VARCHAR, TEXT, BINARY, VARBINARY, and BLOB
Special types: JSON, ENUM, and SET
Special types: POINT and GEOMETRY
NoteIf you want to change a column to an unsupported data type, you can use the
DROP INDEXstatement to delete the CCI, change the data type of the column, and then recreate the CCI.The following table describes the support for changing indexes using the
ALTER TABLEstatement:Statement
Supported
ALTER TABLE ADD PRIMARY KEY
Yes
ALTER TABLE ADD [UNIQUE/FULLTEXT/SPATIAL/FOREIGN] KEY
Yes
ALTER TABLE DROP INDEX
Yes
ALTER TABLE DROP FOREIGN KEY fk_symbol
Yes
ALTER TABLE DROP PRIMARY KEY
No. Prohibited
ALTER TABLE RENAME INDEX
Yes. You can modify the name of a CCI.
ALTER TABLE ALTER INDEX index_name {VISIBLE | INVISIBLE}
No. You cannot modify a CCI.
ALTER TABLE {DISABLE | ENABLE} KEYS
No. You cannot modify a CCI.
FAQ
Can I create a CCI without specifying a sort key?
A: No. You must explicitly specify the sort key in the
CREATE CLUSTERED COLUMNAR INDEXstatement. The sort key and partition key can be different columns. For example, when you create a CCI on thet_ordertable, you can specifyseller_idas the sort key andorder_idas the partition key.Can I create a CCI without specifying a partition key?
A: Yes. If you do not specify a partition key, the primary key is used as the partition key by default, and HASH is selected as the partitioning policy.
How do I view the progress of creating a CCI?
A: You can use DDL management statements to view the current status of the CCI and the execution progress of the DDL task. For more information, see SHOW COLUMNAR INDEX and SHOW DDL.
How do I delete a CCI?
A: You can use the DROP INDEX statement to delete a CCI.