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分析仍然没有走我刚建的索引,那么执行时间怎么平白无故的缩短了呢
深入分析
项目使用 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 类型和原表的数据类型不一致,都改成bigint类型再次用EXPLAN分析发现使用索引了,但是还是不明白开始数据类型不一致的时候没走我新加room_idx 索引查询速度为什么依然变快了八九十倍
|