涉及到的表结构及数据如下:
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中可这么写:同时执行三条语句
这次优化学习了一波,欢迎大家指教,相互讨论。