MySQL 面试系列:为什么MySQL字符串不加引号索引失效?

2022-01-10  本文已影响0人  you的日常

其它MySQL 面试系列:

MySQL 面试系列:如何选择普通索引和唯一索引?
MySQL 面试系列:一条 select 语句在 MySQL 是这样执行的?

MySQL 面试系列:MySQL查询如何进行优化?
MySQL 面试系列:MySQL 常见的开放性问题
MySQL 面试系列:MySQL 性能优化 & 分布式

MySQL 面试系列:MySQL 命令和内置函数
MySQL 面试系列:MySQL 中日志的面试题总结
MySQL 面试系列:MySQL 中锁的面试题总结

MySQL 面试系列:MySQL 事务的面试题总结
MySQL 面试系列:MySQL 索引的面试题总结
MySQL 面试系列:MySQL 基础模块的面试题总结


前几天有一个小伙伴在问为什么 MySQL 字符串不加单引号会导致索引失效,这个问题估计很多人都知道答案。没错,是因为 MySQL 内部进行了隐式转换。

本文就聊聊什么是隐式转换,为什么会发生隐式转换。

一、几大索引失效原因

你肯定在网上看到过非常多关于索引失效原因的文章,但是一定要自己亲手尝试一下,因为版本不同引发的结果不会一致。

1.带头大哥不能死

这局经典语句是说创建索引要符合最左侧原则。

例如表结构为u_id,u_name,u_age,u_sex,u_phone,u_time

创建索引为idx_user_name_age_sex

查询条件必须带上 u_name 这一列。

2.不在索引列上做任何操作

不在索引列上做任何计算、函数、自动或者手动的类型转换,否则会进行全表扫描。简而言之不要在索引列上做任何操作。

3.俩边类型不等

例如建立了索引 idx_user_name,name字段类型为varchar

在查询时使用 where name = kaka,这样的查询方式会直接造成索引失效。

正确的用法为 where name = "kaka"

4.不适当的like查询会导致索引失效

创建索引为 idx_user_name

执行语句为

select * from user where name like "kaka%";

可以命中索引。

执行语句为

select name from user where name like "%kaka";

可以使用到索引(仅在8.0以上版本)。

执行语句为

select * from user where name like ''%kaka";

会直接导致索引失效

5.范围条件之后的索引会失效

创建索引为 idx_user_name_age_sex

执行语句

select * from user where name = 'kaka' and age > 11 and sex = 1;

上面这条sql语句只会命中 name 和 age 索引,sex 索引会失效。

复合索引失效需要查看 key_len 的长度即可。

总结:%在后边会命令索引,当使用了覆盖索引时任何查询方式都可命中索引。

以上就是咔咔关于索引失效会出现的原因总结,在很多文章中没有标注MySQL版本,所以你有可能会看到is null 、or索引会失效的结论。

二、从规则方面说明索引失效的原因

问题的答案就是第3点,两边类型不一致导致索引失效。

下图是表结构,目前这个表存在两个索引,一个主键索引,一个普通索引phone。

分别执行以下两条SQL语句

explain select * from evt_sms where phone = '13020733815';
image

从上图可看出,执行第一条 SQL 没有使用到索引,第二条 SQL 却使用到了索引。

不错,你也发现了两条 SQL 的不同,第二条 SQL 跟第一条 SQL 逻辑一致,不同的是一个查询条件有引号,一个没有。

问题:为什么逻辑相同的 SQL 却是用不了索引

选择索引是优化器大哥的工作,大哥做事肯定轮不到咱们去教,因为大哥有自己的一套规则。

对于优化器来说,如果等号两边的数据类型不一致,则会发生隐式转换。

例如,explain select * from evt_sms where phone = 13020733815;这条SQL语句就会变为 explain select * from evt_sms where cast(phone as signed int) = 13020733815;

由于对索引列进行了函数操作,从而导致索引失效。

问题:为什么会把左侧的列转为int类型呢?

优化器大哥就是根据这个规则进行判断,是把字符串转为数字,还是把数字转为字符串。

若返回1,则把字符串转为数字。

若返回0,则把数字转为字符串。

上一篇 下一篇

猜你喜欢

热点阅读