究竟为什么隐式转换就会导致索引失效呢?
现在有一个普通学生表 S(学号,姓名,年龄,性别,专业)
执行如下语句查看表中索引,共有两个索引
SHOW INDEX FROM s;
sno代表(学号)为主键索引类型为varchar, sage(年龄)普通索引类型为int
现在比较两个sql语句
EXPLAIN SELECT * FROM s WHERE sno = 95020103;
EXPLAIN SELECT * FROM s WHERE sno = '95020103';
上面哪一个会走索引呢?注意sno为varchar类型的主键索引
答案:第一个语句出现索引失效问题!走了全表扫描
第二个语句走了索引
为什么呢?原因是我们在MySQL在执行的时候优化了我们的语句!
因为我们主键索引类型定义为varchar而我们sql语句指定的类型为int
MySQL优化器会直接将索引列隐式转换为int类型 [我们的聚簇索引是根据varchar来建立的!]从而导致了索引失效!
相信你已经有所领悟了!现在再让我们看一下下面俩个语句哪个会走索引:
注意 sage类型为int,且作为普通索引
EXPLAIN SELECT * FROM s WHERE sage = '21';
EXPLAIN SELECT * FROM s WHERE sage = 21;
哪一个会导致索引失效呢?
答案是都会走索引!且执行语句一模一样! why???小伙伴们可能有点懵x了!
好家伙按照控制变量法给你试出来了:MySQL中的 ‘21’ = 21?
答案是:没错!执行如下语句一探究竟
SELECT '21' = 21;
原来MYSQL默认优化语句的时候varchar可以向下主动转型为int;但是int无法转为varchar
【注意:这就是为什么第一个案例出现了索引失效问题!】
总结:
在编写SQL语句层面确实varchar类型可自动转为int类型(优化器做的事)但是int类型无法向上转型为varchar!出现索引失效问题根源在于我们要根据建立索引的相应类型来写具体where后的索引列SQL语句!