目录
一、慢查询日志(slow_query_log)概念
对于SQL和索引的优化问题,我们会使用explain去分析SQL语句。但是真正的企业级项目有成千上万条SQL,我们不可能从头开始一条一条explain去分析。我们从什么地方可以获取那些运行时间长,耗性能的SQL??
当我们去分析项目所涉及的业务的sql效率的时候,应该打开慢查询日志,根据具体的业务、具体的并发量,来预估一个时间上限,整个查询是不能超过这个上限的,设置好后开启业务,压测过程中我们会发现如果哪些sql的查询超过我们预测的时间,那么这些sql都会被记录在慢查询日志当中,然后使用explain分析这些耗时的语句,判断为什么效率低下。就可以知道索引有没有用,或者是没有建索引需要加索引(主键、unique还是二级索引),或者是索引使用到了,但是由于表的数据量太大,花费的时间就是很长,那么此时我们可以把表分成多个小表等,再看有没有分组排序,如果有where又有分组排序,要考虑加联合索引。
慢查询日志相关参数:show variables like '%slow_query%';
(MySQL定义的很多的全局的开关,都是在全局变量中存储,可以用show/set variables查看或者设置全局变量的值)
慢查询日志开关默认是关闭的
慢查询日志的路径:默认在/var/lib/mysql/
下
慢查询日志记录了包含所有执行时间超过参数long_query_time(单位:秒)所设置值的SQL语句的日志,在MySQL上用命令可以查看,如下:
这个值是可以修改的,如下:
现在修改成超过1秒的SQL都会被记录在慢查询日志中!可以设置成0.01秒,表示10毫秒。
二、慢查询日志实践
1. 打开慢查询日志开关
在打开慢查询日志开关的时候,报错表示slow_query_log是一个global的变量(也有只影响当前session的变量,如:long_query_time 、profiling),修改后会影响所有的session,即影响所有正在访问当前MySQL server的客户端。
打开慢查询日志开关成功!
2. 设置合理的、业务可以接受的慢查询时间上限long_query_time
查看另一个session
发现还是默认的10s,故long_query_time只影响当前session
3. 压测执行各种业务
已经超过我们设置的long_query_time=0.1s
4. 查看慢查询日志
慢查询日志路径:/var/lib/mysql/
5. 用explain分析这些耗时的sql语句,从而针对性优化
原来是做了整表搜索,把主键索引树整个扫了一遍。然后再一看paswd作为过滤条件,应该设置索引,即使设置索引了再查看还是用不到索引,然后又发现因为passwd是字符串格式涉及了类型转换,所以用不到索引,正确的sql应该是下面这条语句。
再来总结刚开始这个问题
接下来可以举例子,比如我在做一个业务的时候用到了where过滤条件外加order by,然后用explain分析后有using filesort,涉及了外部排序,为什么会涉及外部排序呢?因为我们数据和索引都是在磁盘上放着呢,如果没有建立合适的索引的话,我们要做order by只能进行外部排序了,这就比较耗时了,然后我试着用where的过滤条件和order by排序的字段建立了联合索引。。。
然后再和和前一篇博客所讲的各种各样出问题的索引结合起来回答,比如类型强转、过滤条件用了MySQL的函数都用不到索引,要考虑进去优化等等。参考回答:MySQL索引常见问题
三、show profiles查看sql具体的运行时间
MySQL一般只显示小数点后两位时间
打开profiling开关,可以显示更详细的时间
没有报错,说明profiling变量只影响当前session