定位慢的原因
- 是否存在周期性波动,如果存在周期性波动,有可能是周期性节点的原因,这样的话,我们可以通过加缓存或是更改缓存失效策略的方式来更新
- 如果增加缓存无法解决问题或是不是周期性问题,我们需要进一步分析查询延迟合卡顿的原因,通过开启慢查询可以帮助我们定位执行慢的SQL语句,我们可以通过设置long_query_time 参数定义慢的阈值,如果SQL执行时间超过了 long_query_time, 则会认为是慢查询,当收集上来这些慢查询之后,我们可以通过分析工具对慢查询进行分析
- 定位执行慢的SQL后,我们就可以针对性的用EXPLAIN查看对应的SQL语句的执行计划,或是使用show profile查看SQL中每一步的时间成本,这样我们就可以了解SQL查询慢是因为执行时间长,还是等待时间长。
- 如果是SQL等待时间长,我们就需要优化服务器参数,比如适当增加数据库缓冲池等,如果SQL执行时间过长,我们就需要考虑是否是索引设计问题,还是查询中关联的表过多,还是因为数据表的字段设计问题导致了这一现象。
- 如果还无法解决问题,我们就需要考虑SQL的查询性能是否到达了瓶颈,如果没有到达性能瓶颈,就需要重新检查,重复以上步骤,如果到达了,就需要考虑增加服务器,采用读写分离架构,或是考虑对数据库进行分库分表,比如垂直分库,垂直分表,水平分表等。
使用慢查询定位执行慢的SQL
慢查询可以帮助我们找到慢的SQL, 使用前我们需要先看下慢查询是否有开启,使用一下命令即可
show variables like '%slow_query_log'
如果看到slow_query_log=OFF,也就是说慢查询日志此时是关闭的,我们可以把该日志打开,注意设置的时候,需要增加global
set global slow_query_log='ON'
然后我们再来看下慢查询日志是否开启,以及慢查询日志的文件位置
show variables like '%slow_query_log%'
接下来我们来看下满查询的时间阈值设置,使用如下命令
show variables like '%long_query_time%'
如果我们想把时间缩短,比如设置为3秒
set global long_query_time=3
我们可以使用MySQL自带的mysqldumpslow贡酒进行统计查询分析。
具体命令参数如下
- -s 采用 order排序方式
- -t 返回前N条数据
- -g 后面可以是正则表达式,对大小写不敏感
mysqldumpslow.pl -s t -t 2 ./xxx.log
如何使用EXPLAIN查看执行计划
定位到慢的SQL后,我们可以使用EXPLAN工具做针对性的分析,比如我们想要了解 product_comment和user表进行联合查询时候所采用的执行计划
EXPLAIN SELECT comment_id, product_id, comment_text, product_comment.user_id, user_name FROM product_comment JOIN user on product_comment.user_id = user.user_id
数据表访问类型所对应的type列是我们所关注的信息,type会分为以下几类
type | 说明 |
---|---|
all | 全数据表扫描 |
index | 全索引表扫描 |
range | 对索引列进行范围查找 |
index_merge | 合并索引,使用多个单列索引搜索 |
ref | 根据索引查找一个或是多个值 |
eq_ref | 搜索时候使用primary key 或是 unique值,常用于多表联合查询 |
const | 常量,表最多有一个匹配行,因为只有一行,在这行的列值,可被优化器认为是常数 |
system | 系统,表只有一行。用const连接类型的特列 |
在这些情况中,all是最坏 的情况,因为采用了全表的扫描,index和all差不多,只不过,index对索引表进行全扫描,这样做的好处是不再需要对数据进行排序,但是开销依然大。
使用SHOW PROFILE查看SQL的具体的执行成本
show profile 相比于explain能看到更进一步的执行解析,包括SQL都做了什么,所花费的时间等,默认情况下,profiling是关闭的,我们可以通过下面的命令开启这个功能
show variables like 'profiling'
set profiling = 'ON'
网友评论