首先,我们先自己定义一下花多少时间算慢查询,我们使用show variables like "%long%";去查看mysql数据里的long_query_time参数,系统默认是10秒,这是不可接受的慢,不过每个系统不一样,就我的系统内部而言,超过0.5秒就可以当做慢查询了。
今天做系统巡查的时候发现一条查询时间达到2.6秒的SQL,这是系统不能接受的,语句如下:
//字段名和表名非真实环境的,做了匿名转换,用abcd等字母替代了
(
SELECT cs.a,cs.b,cs.c,cs.d,cs.e,cs.f,de.a FROM abcd cs LEFT
JOIN efjh de
ON de.b = cs.e
WHERE
cs.e = (SELECT e FROM efjh WHERE i = '490d74c5')
AND cs.j = 1
AND cs.h = 1
ORDER BY cs.i
DESC LIMIT 20
)
上面的语句中de.a,对于结果集来讲,每一行都是一样的,那么我们可以做的一个优化其实是提前把这个数据查询出来,然后用程序把两个数据做拼接即可,而不是使用连接查询,修改后的语句为:
1、先查询de.a
(
SELECT a FROM efjh WHERE i = '490d74c5’
)
2、再查询另一个表的其他数据
(
SELECT a,b,c,d,e,f FROM abcd cs
WHERE e = (SELECT e FROM efjh WHERE i = '490d74c5’)
AND j = 1
AND h = 1
ORDER BY i DESC LIMIT 20
)
经过上述的优化发现时间降低到了1秒多,但是还是不满足系统的需求,那么还有什么因素呢,SQL语句已经经过了优化了,接下来就开始从表里开始找原因。
查询了表结构之后就立马发现了慢的原因了,发现查询条件中的e,j,h这三个字段没有一个是加了索引的,这就是慢的根本原因,给这三个字段加上索引,再次执行SQL语句,发现执行时间立马降低到了0.005秒左右。
总结一下,以后遇到慢查询,首先的第一反应应该是,查询条件所使用的字段是否加了索引。
下面来记录一下分析慢查询过程中用到的一些命令:
1、查看一下慢查询统计是不是已经开启
show variables like "%slow%";如果得到的结果中slow_query_log为on,则代表开启了。
2、如果没有开启,如何去开启慢查询统计
set global slow_query_log='ON';
慢查询日志有两种方式存储,存储在mysql.slow_log的表里,或者存储在主机名加_slow.log文件里面。