新旧项目交接之后,新项目暂时还没有上线,旧项目还要继续维护,遇到一个问题,后台访问某些页面非常慢,在MySQL中show processlist查看执行的sql,手动执行了一下,居然要30s左右。
sql写的也是很6,8个join、2个子查询。但是本身涉及到的表都不大,最大的一个表也就是几万的数据量。其他的只有几十左右。
将子查询的语句先进行查询,问题不大,0.1s左右,但是里面基本上都是重复数据,sql大致是这样的:
select * from xx where column in (select id from yy where column = 'cond')
首先对子查询加了个group by,但是问题依旧,没有明显改善,于是将查询结果直接代替子查询,类似这样:
select * from xx where column in (1,2,4,5,66)
很快,毫秒级,不得其解,网上查了一下,MySQL的子查询存在很大的问题,很不友好,按照我的想法,应该是先查询:
select id from yy where column = 'cond'
得到结果之后再进行外部查询,然而MySQL并不是这么做,看下执行计划:
DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询 。也就是说MySQL先对外面的sql进行查询,select * from xx,得到一个集合。然后根据上一步得到的集合的每一条进行一个查询。也就是说外面有多少结果就进行多少次查询,效率不低才怪