今天在查看每天程序的性能报表时,发现一个url访问速度略慢,深入查找原因后发现是由于一个sql语句的问题引起的,记录在此。
1. 应用场景
业务的场景相对简单,是一个表A与表B的多对多映射,使用了表C记录这种映射关系。
2. 问题分析
原来的sql语句如下:
select * from A as tableA
inner join
(select AID, BID from C) as temp
on temp.AID = tableA.AID
where B.BID = 123
orderby XXX DESC
limit 3;
一个挺简单的业务,A,B表的数据量也不大,大概只在10W左右,但是整个SQL执行下来竟然要差不多100MS,通过explain查看执行计划,如下:
虽然表C中索引都有,但是由于中间那句
(select AID, BID from C) as temp
的原因,导致整张表被扫描了一遍,索引完全失效。
3. 解决方法
既然已经分析出了问题所在,解决思路也就很明显了,即想法办命中索引。就着这个思路,将sql语句稍作修改如下:
select * from A as tableA
where a.ID in
(select AID from C where BID = 123)
orderby XXX DESC
limit 3;
通过explain之后可以看到执行计划如下:
非常好的命中索引,执行时间也提升了近十倍。