遇到的MySQL性能问题记录下

涉及到的表结构及数据如下:

minute_time 点击表名下载

month_show_data 点击表名下载


以前的SQL如下:

#explain
select  
a.minute ,
IF(20=10,IFNULL(b.request_second,0),IF(20=20,IFNULL(ROUND((b.traffic_rcvd_second/1024),2),0),IFNULL(ROUND((b.traffic_sent_second/1024),2),0))) totalrequestSecond  
from  
(select minute from minute_time where minute>=DATE_FORMAT(DATE_ADD(NOW(),interval -6 hour),'%H:%i') and minute<=DATE_FORMAT(NOW(),'%H:%i'))a  
left join  
    (select   
    traffic_sent_second,  
    traffic_rcvd_second,  
    create_time,  
    request_second   
    from   
    month_show_data   
    where  
    type=20  
    and server_zone='All'
    and create_time>= DATE_FORMAT(DATE_ADD(NOW(),interval -6 hour),'%Y-%m-%d %H:%i:%s')  
    )b  
on DATE_FORMAT(b.create_time,'%H:%i')=a.minute 
order by a.minute
结果如下:


explain查询执行计划


通过explain发现type是All,即全表查,并且month_show_data的filtered达到了100,说明SQL里的筛选条件是没有效果的

解释下filtered:显示了通过条件过滤出的行数的百分比估计值。

rows:显示MySQL认为它执行查询时必须检查的行数。多行之间的数据相乘可以估算要处理的行数。

我认为,左关联右边的子句中的条件没有起到作用,导致还是全表查

由此进行优化:

创建临时表进行保存原左关联右边的子句查询结果,再将原左关联左边的子句和临时表再进行左关联查询,返回结果后,最后再删除临时表:


可以发现优化之后,执行时间是天差地别。

再进行EXPLAIN


虽然还是type还是All 全表查,但是它是针对于临时表来说的,rows已经减少到356行,远远小于第一条SQL语句。

在mybatis中可这么写:同时执行三条语句


这次优化学习了一波,欢迎大家指教,相互讨论。

猜你喜欢

转载自blog.csdn.net/chineseyoung/article/details/80703519