存储过程dbms_imci.check_columnar_index()可以解析输入的SQL语句,并得到SQL语句中使用的所有列,并检查这些列是否被列索引覆盖。
- 如果SQL语句中使用了未被列索引覆盖的列,调用该存储过程后会返回这些列所在的库名、表名以及列名。 
- 如果SQL语句中使用的所有列都已经被列索引覆盖,调用该存储过程会返回空的结果集。 
前提条件
- PolarDB集群版本需满足以下条件之一: - PolarDB MySQL版8.0.1版本且修订版本为8.0.1.1.30及以上。 
- PolarDB MySQL版8.0.2版本且修订版本为8.0.2.2.12及以上。 
 
- 您需要具有所操作的表的读(SELECT)权限。 
语法
dbms_imci.check_columnar_index('<query_string>');参数说明
| 参数 | 说明 | 
| query_string | 需要解析的SQL语句。 说明  
 | 
注意事项
- 存储过程名称区分大小写。 
- 使用该存储过程解析SQL语句时,如果SQL语句中的表名前添加了库名,则使用SQL语句中的库名。如果SQL语句中的表名前没有添加库名,则必须使用 - use db_name命令切换至SQL语句中的表所在的库后,再执行该存储过程。
- SQL语句没有特殊的长度限制,但客户端向数据库发送的SQL语句长度受限于 - max_allowed_packet等参数,以及解析SQL语句时使用的- thread_stack参数。
- 如果列存索引不支持SQL语句中使用的列的类型,调用该存储过程时会返回错误信息。 
- SELECT语句可以为Prepared Statement的参数化形式,但不能添加PREPARE ... FROM关键词。 
- 如果SQL语句中使用了 - '或- "等需要转义的字符,则需要按照MySQL的语法规则进行转义。示例如下:- 将SQL语句中的 - '换成- ''。- call dbms_imci.check_columnar_index('select t1.a from t1 where t1.b = ''some_string''');
- 将SQL语句中的 - "换成- ""。- call dbms_imci.check_columnar_index("select t1.a from t1 where t1.b = ""some_string""");
 - 更多转义规则请参见MySQL官网。 
示例
以t1、t2和t3表为例,调用存储过程检查SQL语句中是否存在未被列存索引覆盖的列。
- 执行如下命令,切换至 - test库。- use test;
- 执行如下命令,创建 - t1、- t2和- t3表,其中- t3表的所有列都被列索引覆盖。- create table t1 (a int, b int) engine = innodb; create table t2 (a int, b int) engine = innodb; create table t3 (a int, b int) engine = innodb comment 'columnar=1';
- 调用存储过程,检查SQL语句中是否有未被列索引覆盖的列。 - SQL语句中的列为 - t1和- t2表中的列。- call dbms_imci.check_columnar_index('select count(t1.a) from t1 inner join t2 on t1.a = t2.a group by t1.b');- 执行结果如下: - +--------------+------------+-------------+ | TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | +--------------+------------+-------------+ | test | t1 | a | | test | t1 | b | | test | t2 | a | +--------------+------------+-------------+ 3 rows in set (0.01 sec)- SQL语句中使用了 - t1.a、- t1.b以及- t2.a三列,且这三列没有被列索引覆盖。因此,调用该存储过程时,返回这三列对应的库名、表名以及列名。
- SQL语句中的列为表 - t3中的列。- call dbms_imci.check_columnar_index('select a, b from t3');- 执行结果如下: - Empty set (0.00 sec)- 表 - t3中的所有列都被列索引覆盖。因此,调用该存储过程时,返回空结果集。