本文將介紹如何建立並使用列存索引(CCI)功能。
版本限制
注意事項
僅PolarDB-X 2.0企業版的主執行個體上支援建立列存索引。更多資訊,請參見列存索引建立指南。
建立CCI時的相關約束:
不支援通過任何方式使用首碼索引。
建立CCI時必須指定索引名。
建立CCI預設包含主表的所有列,且建立後會隨著主表的列調整而自動調整,不支援手動調整列。
建立CCI不會額外建立任何局部索引。
索引定義中,排序鍵的
LENGTH
參數將被忽略。
主執行個體、唯讀執行個體、列存唯讀執行個體都支援
SHOW INDEX
等查詢命令。更多資訊,請參見SHOW COLUMNAR INDEX、SHOW COLUMNAR OFFSET、SHOW COLUMNAR STATUS。DDL相關限制,請參見使用限制。
文法
PolarDB-X對MySQL DDL的文法進行了擴充,增加定義CCI的文法,使用方式與在MySQL上建立索引一致,其文法如下所示:
CREATE
CLUSTERED COLUMNAR INDEX index_name
ON tbl_name (index_sort_key_name,...)
[partition_options]
# 分區策略定義
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
# 分區函數定義
partition_func:
YEAR
| TO_DAYS
| TO_SECOND
| UNIX_TIMESTAMP
| MONTH
# 分區列表定義
partition_list_spec:
hash_partition_list
| range_partition_list
| list_partition_list
# Hash/Key分區表列定義
hash_partition_list:
PARTITIONS partition_count
# Range/Range Columns分區表列定義
range_partition_list:
range_partition [, range_partition ...]
range_partition:
PARTITION partition_name VALUES LESS THAN {(expr | value_list)} [partition_spec_options]
# List/List Columns分區表列定義
list_partition_list:
list_partition [, list_partition ...]
list_partition:
PARTITION partition_name VALUES IN (value_list) [partition_spec_options]
樣本
執行如下代碼建立表t_order
,再基於t_order
建立列存索引cc_i_seller
:
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;
建立列存索引代碼詳解如下:
CLUSTERED COLUMNAR:關鍵字,用於指定添加的索引類型為CCI。
主表:
t_order
是分區表,分區的拆分方式為按照order_id
列進行雜湊分割。索引名:索引的名稱,用於在SQL語句中指定該索引。
排序鍵:索引的排序鍵,即資料在索引檔案中按照該列有序儲存。
索引分割區子句:索引的分區演算法,與
CREATE TABLE
中分區子句的文法一致,其中order_id
為雜湊列。索引定義子句:
CLUSTERED COLUMNAR INDEX `cc_i_seller` ON t_order (`seller_id`) partition by hash(`order_id`) partitions 16
。
如何在查詢中使用CCI
CCI建立完成後,可以通過如下方式指定查詢使用的索引表:
通過HINT指定索引的方式
文法:
FORCE INDEX({index_name})
樣本:
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";
索引選擇的方式
對於帶有列存索引的主表查詢,PolarDB-X會自動選擇出最佳化器認為代價最低的索引表(目前僅支援在列存唯讀執行個體上使用列存索引查詢)。
不使用指定索引(IGNORE INDEX)
文法:
IGNORE INDEX({index_name},...)
以下代碼可以指定最佳化器不使用索引cc_i_seller
:
SELECT t_order.id,t_order.order_snapshot FROM t_order IGNORE INDEX(cc_i_seller) WHERE t_order.seller_id = 's1';
使用指定索引(USE INDEX)
文法:
USE INDEX({index_name},...)
以下代碼可以指定最佳化器使用索引cc_i_seller
:
SELECT t_order.id,t_order.order_snapshot FROM t_order USE INDEX(cc_i_seller) WHERE t_order.seller_id = 's1';
使用限制
使用限制主要分為以下三類:
建立CCI時,主鍵、排序鍵和分區鍵的資料類型具有一定限制。
在包含CCI的表中,執行DDL具有一定限制,目前僅支援常見的DDL語句。
執行DDL變更列資料類型時,支援有限的資料類型。
資料類型限制
資料類型 | 主鍵 | 排序鍵 | 分區鍵 | |
數實值型別 | BIT (UNSIGNED) | 支援 | 支援 | 不支援 |
TINYINT (UNSIGNED) | 支援 | 支援 | 支援 | |
SMALLINT (UNSIGNED) | 支援 | 支援 | 支援 | |
MEDIUMINT (UNSIGNED) | 支援 | 支援 | 支援 | |
INT (UNSIGNED) | 支援 | 支援 | 支援 | |
BIGINT (UNSIGNED) | 支援 | 支援 | 支援 | |
時間類型 | DATE | 支援 | 支援 | 支援 |
DATETIME | 支援 | 支援 | 支援 | |
TIMESTAMP | 支援 | 支援 | 支援 | |
TIME | 支援 | 支援 | 不支援 | |
YEAR | 支援 | 支援 | 不支援 | |
字串類型 | CHAR | 支援 | 支援 | 支援 |
VARCHAR | 支援 | 支援 | 支援 | |
TEXT | 支援 | 支援 | 不支援 | |
BINARY | 支援 | 支援 | 支援 | |
VARBINARY | 支援 | 支援 | 支援 | |
BLOB | 支援 | 支援 | 不支援 | |
浮點數類型 | FLOAT | 不支援 | 不支援 | 不支援 |
DOUBLE | 不支援 | 不支援 | 不支援 | |
DECIMAL | 不支援 | 不支援 | 不支援 | |
NUMERIC | 不支援 | 不支援 | 不支援 | |
特殊類型 | JSON | 不支援 | 不支援 | 不支援 |
ENUM | 不支援 | 不支援 | 不支援 | |
SET | 不支援 | 不支援 | 不支援 | |
POINT | 不支援 | 不支援 | 不支援 | |
GEOMETRY | 不支援 | 不支援 | 不支援 |
因為不同分區演算法支援的資料類型稍有不同,所以詳細區別,請詳見資料類型說明。
DDL語句限制
您可以使用如下語句來控制是否允許在包含CCI的表中執行DDL(true
為允許、false
為不允許):
SET [GLOBAL] forbid_ddl_with_cci = [true | false];
含CCI的主表及CCI本身的DDL支援情況如下:
操作類別
操作名稱
樣本SQL
支援情況
主表
刪除表
DROP TABLE tbl_name;
支援
清空表
TRUNCATE TABLE tbl_name;
支援
重新命名表
ALTER TABLE old_tbl_name RENAME TO new_tbl_name;
RENAME TABLE old_tbl_name TO new_tbl_name;
支援
重新命名多個表
RENAME TABLE tbl_name_a to tbl_name_b, tbl_name_c to tbl_name_d;
支援
添加列
ALTER TABLE tbl_name ADD col_name TYPE;
支援
刪除列
ALTER TABLE tbl_name DROP COLUMN col_name;
支援
修改列類型
ALTER TABLE tbl_name MODIFY col_name TYPE;
支援
重新命名(修改)列
ALTER TABLE tbl_name CHANGE old_col new_col TYPE;
支援
修改列預設值
ALTER TABLE tbl_name ALTER COLUMN col_name SET DEFAULT default_value
;ALTER TABLE tbl_name ALTER COLUMN col_name DROP DEFAULT;
支援
無鎖變更列類型
ALTER TABLE tbl_name MODIFY col_name TYPE, ALGORITHM = omc;
支援
ALTER TABLE
多重操作ALTER TABLE tbl_name MODIFY col_name_a, DROP COLUMN col_name_b;
支援
產生列
-
不支援
分區變更
-
不支援
列存索引(CCI)
建立CCI
CREATE CLUSTERED COLUMNAR INDEX cci_name;
ALTER TABLE tbl_name ADD CLUSTERED COLUMNAR INDEX cci_name;
支援
刪除CCI
DROP INDEX cci_name ON TABLE tbl_name;
ALTER TABLE tbl_name DROP INDEX cci_name;
支援
更改CCI名稱
ALTER TABLE tbl_name RENAME INDEX cci_name_a TO cci_name_b;
支援
增加CCI Range分區
ALTER TABLE `tbl_name`.`cci_name` ADD PARTITION;
支援
其他CCI分區變更
-
不支援
ALTER TABLE
變更列時,相關約束如下:語句
是否支援變更主鍵
是否支援變更索引分割區鍵
是否支援變更排序鍵
ADD COLUMN
不支援
不涉及
不涉及
ALTER COLUMN SET DEFAULT、ALTER COLUMN DROP DEFAULT
不支援
不支援
不支援
CHANGE COLUMN
不支援
不支援
不支援
DROP COLUMN
不支援
不支援
不支援
MODIFY COLUMN
不支援
不支援
不支援
說明除了主鍵列、主表/索引分割區鍵列、排序鍵列這些列之外,其他列都支援
ADD COLUMN
、ALTER COLUMN SET DEFAULT
、ALTER COLUMN DROP DEFAULT
、CHANGE COLUMN
、DROP COLUMN
、MODIFY COLUMN
操作。MODIFY/CHANGE COLUMN
語句的類型限制如下:支援類型
不支援類型
數實值型別:BIT (UNSIGNED),TINYINT (UNSIGNED),SMALLINT (UNSIGNED),MEDIUMINT (UNSIGNED),INT (UNSIGNED),BIGINT (UNSIGNED)
時間類型:DATETIME
浮點數類型:FLOAT,DOUBLE,DECIMAL、NUMERIC
字串類型:CHAR,VARCHAR
字串類型:TEXT,BINARY,VARBINARY,BLOB
時間類型:TIMESTAMP、TIME、YEAR
特殊類型:JSON、ENUM、SET、POINT、GEOMETRY
說明如果遇到不支援的類型,您可以先使用
DROP INDEX
刪除列存索引,變更列類型後再重新建立列存索引。ALTER TABLE
語句變更索引的支援情況如下:語句
是否支援
ALTER TABLE ADD PRIMARY KEY
支援
ALTER TABLE ADD [UNIQUE/FULLTEXT/SPATIAL/FOREIGN] KEY
支援
ALTER TABLE DROP INDEX
支援
ALTER TABLE DROP FOREIGN KEY fk_symbol
支援
ALTER TABLE DROP PRIMARY KEY
禁止
ALTER TABLE RENAME INDEX
支援修改CCI名稱
ALTER TABLE ALTER INDEX index_name {VISIBLE | INVISIBLE}
不支援修改CCI
ALTER TABLE {DISABLE | ENABLE} KEYS
不支援修改CCI
常見問題
建立列存索引時能否不指定排序鍵?
答:不能。必須在
CREATE CLUSTERED COLUMNAR INDEX
語句中顯式指定排序鍵。排序鍵與分區鍵可以是完全不同的列。例如在t_order
表上建立CCI時,可以指定seller_id
作為排序鍵,order_id
作為分區鍵。建立列存索引時能否不指定分區鍵?
答:可以。如果沒有指定分區鍵,則預設選擇主鍵作為分區鍵,並選擇HASH作為分區策略。
如何查看建立列存索引的進度?
答:可以通過DDL管理語句查看列存索引當前的狀態和DDL任務的執行進度。詳細資料,請參見SHOW COLUMNAR INDEX和SHOW DDL。
如何刪除列存索引?
答:可以通過DROP INDEX刪除已經成功建立的列存索引。