大家是否想到了一些方法?
【优化后的SQL】
select o.id,o.no,s_order.no, (select sum(sot.count) from seller_order so left join seller_order_item sot on so.id = sot.seller_order_id where so.id =s_order.id ), (select sum(osat.count) from seller_order_after_sale osa left join seller_order_after_sale_item osat on osa.id = osat.after_sale_id where osa.seller_order_id = s_order.id ) from buyer_order o left join seller_order s_order on o.id = s_order.buyer_order_id where o.addTime >='2019-05-01' order by o.id limit 0,10
【优化的SQL分析】
- 很直观的发现,我们把group by去掉了,因为按照 order.id,s_order.id 分组,实际只对 buyer_order和seller_order表进行连接,逻辑上是一样的进行了分组。
- group by不使用的话我们就减少了CPU对数据分组的处理,而且我们只连接主要的表数据,减少了加载到内存中的数据。
- 以上的操作就完成了我们之前说的先对数据分页。我们取出了10条数据。
- 接着我们再对10条数据的销售出去的商品数量和售后的数量进行统计
- 这时候大家发现,我们其实只对分页出来的10条数据进行统计,原来是将所有的数据分组统计后取10条。可以发现我们这样操作大大减少了对数据的统计处理。我们只需要统计我们需要的数据。
以上优化的效果可能远远超出大家的想象。
实际工作中连表的数比我们例子中的要多,未优化的SQL在执行未分页的时候发现一共有70万的数据,我们分页取出10条数据花了10+秒以上的时间,数据量不大但是大部分的时间都消耗在了分组和数据统计,大家可以试着写一段代码对这些数据进行分组和统计,就能明白其中的复杂性。
而实际上无论取出10条和全部取出,时间基本上一样的(不考虑IO),因为先进行了统计。
优化后的SQL,加载到内存中只有2万左右的数据,而且不进行统计,先取出10条数据,然后再对10条数据进行统计,逻辑上比之前的简单多了。优化后的SQL执行时间在20毫秒以内。
其实如果在订单表和售后表都记录了对应的数量,连表数还要少,还不需要进行子查询。有时候设计表的时候还是需要考虑一下统计的需要。
到此这篇关于MYSQL Left Join优化(10秒优化到20毫秒内)的文章就介绍到这了,更多相关MYSQL Left Join优化内容请搜索
更多SQL内容来自木庄网络博客