Mysql加了索引查询速度变快但是使用EXPLANE分析仍然没走索引

101 阅读2分钟

Mysql加了索引查询速度变快但是使用EXPLANE分析仍然没走索引

背景

最近在公司优化了一条sql,本来sql查询需要3秒左右,在某个列上加了索引之后速度变为了50毫秒左右,之后使用执行计划查看仍然没有走刚刚加的索引

案例SQL

SELECT
 某些字段
FROM
 表A AS a
 LEFT JOIN 表B as b ON a.rom_id = b.id 
WHERE a.room_id IN (
 SELECT
  f.id 
 FROM
  表D as d
  LEFT JOIN 表E as e ON 条件
  LEFT JOIN 表F as f ON 条件
  LEFT JOIN 表G as g ON 条件
 WHERE
  e.account IN ( 'X01', 'X02') GROUP BY
  f.id 
 ) 
GROUP BY
 b.id;

上面的sql有点小复杂,重点在于room_id in (SELECT ...),一开始案例sql要执行3s,在a表的room_id加索引之后,案例sql执行时间变为了50毫秒左右,但是使用EXPLAN分析仍然没有走我刚建的索引,那么执行时间怎么平白无故的缩短了呢

红框部分是新加的索引,也是让sql执行变快的那个索引

深入分析

项目使用 Springboot + mybatis-plus开发,sql执行时间统计是在代码中进行的,项目的id字段采用varchar(32)类型存储,例:1079017124602032139,之后看了些会导致索引失效的文章参考了一下,虽然我的索引并没有失效,导致索引失效的原因之一是发生了隐式转换,例如

--索引生效
SELECT * FROM a where id = 1
--索引失效
SELECT * FROM a where id = '1'

上述sql就是发生了隐式转换导致索引失效 但是我的sql并没有发生这种情况,room_id in () 是直接跟的sql查询,并没有发生隐式转换 于是定位问题可能发生在 in 里面的sql语句 单独执行 in 里面的sql语句,执行结果如下 单独执行的结果

猜想

是不是 in 里面是不是发生隐式转换呢 把varchar类型的转换成了 bigint 类型的数据呢,把 in 里面的数据替换掉,如下sql

SELECT
 某些字段
FROM
 表A AS a
 LEFT JOIN 表B as b ON a.rom_id = b.id 
WHERE a.room_id IN ('1479015132404101121','1479016368205443073','1479017124602032130','1479017753365950465') 
GROUP BY
 b.id;

再次查看执行计划 在这里插入图片描述 这次发现已经走索引了,是不是sql内部做了什么转换呢,到现在还是不解,等候mysql大佬来解答

后续进展

后来发现加rom_id类型和原表的数据类型不一致,原表的id是bigint,都改成bigint类型再次用EXPLAN分析发现使用索引了,但是还是不明白开始数据类型不一致的时候没走我新加room_idx索引查询速度为什么依然变快了八九十倍