重建列存索引

本文为您介绍如何OnLine重建列存索引(Clustered Columnar Index,CCI)。

前提条件

  • 需要存在已经创建的列存索引。

  • 重建时需确保Online且无锁的,不会影响列存相关的在线流量,不会影响行存业务。

注意事项

实例版本需为5.4.20-20250714及以上。

说明

背景信息

在使用列存索引(CCI)的过程中,可能会遇到需要调整CCI的排序键和分区键的多种情况。这些情况调整通常需通过重建索引来实现,以优化性能并适应业务变化。

以下是常见的需要修改列存索引设计的场景:

  • 业务测试与性能优化:在初期进行业务测试时,基于当前的数据访问模式创建了列存索引。然而,测试结果显示索引的查询性能未达到预期目标。此时,可能需要重新设计列存索引的排序键和分区键,以更好地匹配查询模式和数据分布,从而提升性能。

  • 业务需求变更与表结构调整:随着业务的发展,数据库表的结构发生了变化,包括新增或删除字段、修改字段类型等。同时,相关的业务SQL查询也发生了调整。这些变更可能导致现有的列存索引不再适配新的查询需求,因此需要重新设计索引的排序键和分区键,以确保索引的高效性和适用性。

  • 数据分布与增长模式变化:随着数据量的持续增长,原有的分区策略和分区数量可能无法有效支撑新的数据规模。或者,列存索引的使用场景发生变化,需要根据时间列等特殊列进行分区。需要调整分区键或重新定义分区策略。

  • 兼容性与升级需求:在列存索引有重大更新时,现有的列存索引结构可能需要调整以兼容新版本的特性。这种情况下,需要通过重建索引来应用新的设计方案。

语法

变量设置

说明

重建CCI时,系统会先在表内创建一个新的CCI,再删除旧的CCI,因此必须先设置该变量。

SET GLOBAL MAX_CCI_COUNT = 2;

允许在一张表内最多建立两个CCI,当表内已经存在多个CCI时,请将此值设置的更大。

重建语法

同步处理重建

通过ALTER TABLE REBUILD语法对指定的CCI进行重建,CCI的具体定义可参见创建和使用CCI

ALTER TABLE tbl_name REBUILD ClUSTERED COLUMNAR INDEX index_name [CCI DEFINITION]; 
说明
  • 指定的表和CCI必须存在,否则会报错CCI不存在。

  • 归档CCI不允许重建。

异步处理重建

当数据量比较大时,由于重建的时间比较长,推荐通过异步的方式执行:

ALTER TABLE tbl_name REBUILD ClUSTERED COLUMNAR INDEX index_name [CCI DEFINITION] ASYNC=TRUE;

示例

# 创建一个带有列存索引的表,排序键和分区键都是id
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,
	CLUSTERED COLUMNAR INDEX `cci_test` (`id`) PARTITION BY KEY(`id`) PARTITIONS 4,
	PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8 AUTO_INCREMENT = 2
PARTITION BY KEY(`id`)
PARTITIONS 16;

# 更改排序键和分区数,重建列存索引
ALTER TABLE `t_order` REBUILD ClUSTERED COLUMNAR INDEX `cci_test`(`seller_id`) PARTITION BY KEY(`id`) PARTITIONS 16;

# 查看新的表结构
SHOW CREATE TABLE t_order\G
*************************** 1. row ***************************
       Table: t_order
Create 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,
	PRIMARY KEY (`id`),
	CLUSTERED COLUMNAR INDEX `cci_test` (`seller_id`)
		PARTITION BY KEY(`id`)
		PARTITIONS 16
) ENGINE = InnoDB DEFAULT CHARSET = utf8
PARTITION BY KEY(`id`)
PARTITIONS 16