问题: 如何从一个大项目中,迅速定位执行速度慢的语句(定位慢查询)。
首先了解mysql数据库的一些运行状态如何查询(比如想知道当前mysql 运行的时间/一共执行了多少次)
show status
常用的:
show status like 'uptime'; show status like 'com_select'; show status like 'com_insert';......类推 update delete show [session|global] status like ....... 默认是session会话,指取出当前窗口的执行,如果你想看所有(从mysql启动到现在,则应该 global); show status like 'connections'; //显示连接数 show status like 'slow_quries'; //显示慢查询次数
如何去定位慢查询?
- 修改mysql慢查询
show variables like 'long_query_time'; 默认为10s
- 设置慢查询秒数:
set long_query_time = 1;
这时如果出现一条语句 执行时间超过1秒,就会统计到;
如何把慢查询的sql记录到我们的一个日志中,在默认的情况下,mysql不会记录慢查询。需要在启动mysql的时候指定记录慢查询。
开启慢查询:
mysql> set global slow_query_log = on;
查看slow_query_log参数
mysql> show variables like '%slow_query_log';
还可以直接编辑:
vim /etc/my.cnf
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/remotejob-01-slow.log
long_query_time=1
重启mysql后生效:service mysqld restart;
在慢查询日志文件里即可查看慢sql:
定位完慢sql后,mysql5.5 以后加了一个profile设置,可以查看到具体语句的执行步骤:
1. 查看profile是否开启
mysql> show variables like 'profiling';
2. 如果没开启,则开启
mysql> set profiling = on;
3. 查看执行的sql语句
mysql> show profiles;
SQL语句优化:
1.SQL语句的时间花在哪儿?
答: 等待时间、执行时间
这两个时间并非孤立的,如果单条语句执行的快了,对其他语句的锁定也就减少了,所以,我们来分析如何降低执行时间。
2.sql 语句的执行时间,花在哪儿?
答:
a: 查----沿着索引查,甚至全表扫描
b: 取----查到行后,把数据取出来(sending data)
3.sql语句的优化思路
答: 不查,通过业务逻辑来计算
必须要查:尽量走在索引上查询行
取时,取尽量少的列
比如: select * from tableA 就取出所有列,不建议
比如: select * from tableA,tableB 取出A,B 表的所有列
4. 如何定量分析查多少行,和是否沿着索引查?
答:用explain 分析