这里说明列存索引 CSI 的相关操作。
注意:说明:
注意:对于生产系统而言,开启和创建列存相当于生产变更,需要遵守生产变更流程。为了降低变更风险,TDSQL-C MySQL 版提供了一些验证能力(流量回放),你可以通过 流量回放 来评估列存的使用效果,然后再决定是否在生产系统中开启和创建列存索引。
一、前提条件
内核版本为 TDSQL-C MySQL 版8.0 3.1.20.001及以上。
注意:说明:
注意:针对只读实例而言,符合版本要求的情况下,4核以上的只读实例才可以开启列存索引功能。
二、开启或关闭 CSI
注意:说明:
注意:当前暂时不支持开启或关闭 CSI 操作,如有特殊需要,请 提交工单 反馈。
1. 在集群列表页,根据实际使用的视图模式进入实例详情页。
页签视图列表视图1. 登录 TDSQL-C MySQL 版控制台,在左侧集群列表,单击目标集群,进入集群管理页。2. 在集群详情下,找到目标实例,单击实例 ID 后的详情,进入实例详情页。1. 登录 TDSQL-C MySQL 版控制台,在集群列表,找到需要修改字符集的集群,单击集群 ID,进入集群管理页面。2. 在集群管理页面,选择实例列表页,找到要开启或关闭列存索引的只读实例,单击实例 ID,进入实例详情页。
2. 在实例详情页的实例形态后,单击修改图标。
3. 在弹窗下,选择操作时间,勾选“在操作过程中,会有秒级别闪断,请确保业务具备重连机制”,单击确定。
操作时间
·立即执行:立即执行实例形态的切换。
·维护时间内:在你设置的实例维护时间内执行,修改维护时间请参见 修改实例维护时间。
注意:说明:
三、列存配置
为了让查询更好的使用列存索引能力,你可参考 参数配置与监控项 进行列存配置。
四、创建和删除 CSI
CREATE TABLE t (c1 INT, c2 INT, c3 INT);INSERT INTO t VALUES (1, 2, 3);
注意:说明:
注意:DDL 需要在 RW 上执行。
创建列存索引支持两种方式:
·使用列存注释语法。
·使用 COLUMNSTORE 关键字。
推荐使用列存注释语法,原因如下:
·COLUMNSTORE 属于新增关键字,现有工具链和生态可能存在兼容性问题。
·列存注释默认创建全字段列存索引,字段发生变更时会自动同步,维护成本更低。
·若使用 COLUMNSTORE 关键字创建列存索引,则需要手动维护字段列表,字段变更时需同步调整索引定义。
五、列存注释语法(推荐)
建表时包含列存索引:
— 列存注释(推荐,全索引)CREATE TABLE t (c1 INT, c2 INT, c3 INT) COMMENT='COLUMNAR=1';
用单独的语句创建列存索引:
— 列存注释(推荐,全索引)ALTER TABLE t COMMENT 'COLUMNAR=1';
可以通过 SHOW CREATE TABLE table_name FULL 确认表上有没有列存。注意,列存索引使用了新关键字 COLUMNSTORE ,默认不打印以避免影响工具兼容,可以使用 FULL 控制打印。
用列存注释创建的列存索引:
— SHOW CREATE TABLE t FULLCREATE TABLE `t` ( `c1` int DEFAULT NULL, `c2` int DEFAULT NULL, `c3` int DEFAULT NULL, COLUMNSTORE KEY `_default_csi_` (`c1`,`c2`,`c3`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='COLUMNAR=1'
删除索引:
— 列存注释(推荐)ALTER TABLE t COMMENT 'COLUMNAR=0';
六、列存关键字语法
注意:工具生态不一定兼容列存关键字 COLUMNSTORE,而且列存索引字段是固定的,不会自动同步新加字段,因此不建议使用。
建表时包含列存索引:
— 列存关键字(固定字段索引 csi (c1,c2,c3))CREATE TABLE t (c1 INT, c2 INT, c3 INT, COLUMNSTORE INDEX csi);
用单独的语句创建列存索引:
— 列存关键字 (固定字段索引 csi (c1,c2,c3))ALTER TABLE t ADD COLUMNSTORE INDEX csi;
删除索引:
— 列存关键字创建的索引名ALTER TABLE t DROP KEY `csi`;
七、执行 SQL
EXPLAIN 对于数据表访问会打印 Csi Scan。你可以通过数据库代理接入,满足阈值和兼容检查的 SQL 会自动在列存节点上执行。也可以直连列存 RO 执行 SQL。
— 小数据量测试设置,生产系统请务必使用有意义的值– SET columnstore_cost_threshold = 0;– explain analyze …– explain format=tree …select max(col1) from t1 where col2 < col3;
以下是执行计划打印结果:
| physical_plan -> Ungrouped Aggregate: max(#0) -> Projection: col1 (rows=1) -> Projection: #11 (rows=1) -> Projection: NULL #6 NULL #5 NULL #4 NULL #3 NULL #2 NULL #1 NULL #0 NULL (rows=1) -> Projection: NULL #2 NULL #1 NULL #0 NULL (rows=1) -> Csi Scan Table: test.t1 Projections: col2 col3 col1 (rows=1)
八、重命名 CSI
开启列存索引 CSI 后,重命名列存索引 CSI 的命令如下:
ALTER TABLE table_name RENAME index old_index_name to new_index_name;
九、列存索引 CSI HINT 语句
1. 强制执行行存执行/列存执行。
·强制执行行存执行
SELECT a FROM t IGNORE INDEX (csi);
·强制执行列存执行
SELECT a FROM t FORCE INDEX (csi);
2. 同时使用 HINT 执行并行查询与列存索引。
SELECT /*+PARALLEL(2)*/ a FROM t FORCE INDEX (csi);
十、创建表和列存索引示例
CREATE TABLE t (a int, columnstore index csi (a));INSERT INTO t VALUES (0), (1), (2);SHOW CREATE TABLE t; SHOW INDEX FROM t;
执行结果如下:
MySQL [test]> CREATE TABLE t (a int, columnstore index csi (a));Query OK, 0 rows affected (0.01 sec)MySQL [test]> INSERT INTO t VALUES (0), (1), (2);Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 MySQL [test]> SHOW CREATE TABLE t; +——-+—————————————————————————————————————+ | Table | Create Table |+——-+—————————————————————————————————————+| t | CREATE TABLE `t` ( `a` int DEFAULT NULL, COLUMNSTORE KEY `csi` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |+——-+—————————————————————————————————————+MySQL [test]> SHOW INDEX FROM t;+——-+————+———-+————–+————-+———–+————-+———-+——–+——+————-+———+—————+———+————+| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |+——-+————+———-+————–+————-+———–+————-+———-+——–+——+————-+———+—————+———+————+| t | 1 | csi | 1 | a | NULL | 1 | NULL | NULL | YES | COLUMNSTORE | | | YES | NULL |+——-+————+———-+————–+————-+———–+————-+———-+——–+——+————-+———+—————+———+————+1 row in set (0.00 sec)
十一、INDEX HINT 使用
1. 强制语句使用列存索引。
SELECT a FROM t FORCE INDEX (csi);EXPLAIN FORMAT=TREE SELECT a FROM t FORCE INDEX (csi);
执行结果:
MySQL [test]> SELECT a FROM t FORCE INDEX (csi);+——+| a |+——+| 0 || 1 | | 2 |+——+3 rows in set (0.00 sec)MySQL [test]> EXPLAIN FORMAT=TREE SELECT a FROM t FORCE INDEX (csi); +—————————————————————+| EXPLAIN | +—————————————————————+| -> COLUMNSTORE Index scan on t using csi (cost=1.30 rows=3) |+—————————————————————+1 row in set (0.00 sec)
2. 强制语句不使用列存索引(行存执行)。
SELECT a FROM t IGNORE INDEX (csi);EXPLAIN FORMAT=TREE SELECT a FROM t IGNORE INDEX (csi);
执行结果:
MySQL [test]> SELECT a FROM t IGNORE INDEX (csi);+——+| a |+——+| 0 || 1 | | 2 |+——+3 rows in set (0.00 sec)MySQL [test]> EXPLAIN FORMAT=TREE SELECT a FROM t IGNORE INDEX (csi);+—————————————–+| EXPLAIN |+—————————————–+| -> Table scan on t (cost=0.55 rows=3) |+—————————————–+1 row in set (0.00 sec)
十二、查看 CSI 索引创建情况
·show create table TABLE
注意:说明:
注意:默认不显示 COLUMNSTORE 前缀,需要指定开关 columnstore_display_in_show_create=1,才会显示。
·show index from TABLE
·explain format=tree
注意:说明:
注意:开启 CSI 后,要查看 CSI 索引创建情况,也可通过 explain format=tree 查看执行计划算子是否有 COLUMNSTORE 前缀(有则表示算子采用了列式执行),来得知该算子是否使用列式执行。只有指定 format=tree 时,才显示 COLUMNSTORE 前缀,不指定格式则默认不显示 COLUMNSTORE。