存储过程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
中的所有列都被列索引覆盖。因此,调用该存储过程时,返回空结果集。