MySQL:explain结果中Extra:Impossible WHERE noticed after reading const tables问题
作者:段晓慢
前情提要
上午有同事突然找我,向我反馈说在对MySQL中的语句进行explain解析的时候,explain的结果中table、type、possible_keys、key等关键性字段都是空的,什么信息都得不到,而当把其中一个字段phone,类型是varchar的单引号去掉了之后,也就是说把where phone='13800138000'
改为where phone=13800138000
之后,再执行explain就能得到explain的关键性字段的结果了。
这个就让我很纳闷,不合常理啊,字段的隐式转换正常来说这种情况应该会导致索引失效才对啊,现在竟然是反之生效,刷新了我们的认知。
我就说了下面一句话:
一个不合常理的现象往往都是由于一个不起眼的或者平时被我们忽略的点所造成的
出现的情况
这种非常理所能解释通的现象,引起了我的好奇心。
从上图中看到Extra:Impossible WHERE noticed after reading const tables,字面上的意思是:读取const tables表之后,没有发现匹配的行。
其实,这个跟MySQL的版本有关,在 MySQL 5.7.17 下的执行结果中可以发现同样的表结构、同样的数据、同样的查询语句,Extra 中的显示的内容为“no matching row in const table”,这句话理解起来就容易多了。
原因
产生“ Impossible WHERE noticed after reading const tables”的原因是这样的,MySQL在 EXPLAIN 之前会优先根据这一条件查找出对应的记录,并用记录的实际值替换查询中所有使用到的该表属性。
这是因为满足以下四个条件时,就会使得针对该表的查询最多只能产生一条命中结果,在该表无法命中数据的情况下就会提示“在 const table 表中没有找到匹配的行”,而这个 “const table”就指的是满足下面四个条件的表。
这是 MySQL 的一个优化策略。
- 当查询条件中包含了某个表的主键或者非空的唯一索引列
- 该列的判定条件为等值条件
- 目标值的类型与该列的类型一致
- 目标值为一个确定的常量
而我们的这张表user_info
的这个查询语句刚好符合这4个条件,原因:
1、phone是非空的唯一索引列;
2、phone= '13800138000’是等值条件
3、phone是字符串类型,'13800138000’也是字符串类型
4、13800138000是一个确定的常量
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。