一、前言 上一篇我们说了腾讯一面:说一说MySQL中索引的底层原理,相信你对索引有个很清晰的认识了,这一篇我们来说一说慢SQL的排查以及调优。为啥面试官要问这个问题,其实跟上一篇的索引底层原理有一定关联关系的,一般慢SQL很大一部分原因对索引底层原理不够特别了解导致的,比如没建索引、索引失效、索引没满足最左前缀匹配原则导致慢SQL,像腾讯这样数据量很大的公司,人家肯定有专门的DBA去做优化的,面试官考察的主要是你排查问题的能力以及知道索引的底层原理、以及知道优化的方向,不至于让你进来把人家规规矩矩的数据库搞乱了。 我们下面直接进入正题了,首先来说下怎么排查慢SQL的。二、开启慢查询日志 MySQL中与慢SQL有关的几个重要系统变量如下: 参数 含义 slowquerylog 是否启用慢查询日志,ON为启用,OFF为未启用,默认为OFF。开启会影响性能,MySQL重启会失效。 slowquerylogfile 指定慢查询日志文件的路径和名字,缺省文件名hostnameslow。log。 longquerytime 执行时间超过该值才记录到慢查询日志,单位为秒,默认为10。 logoutput 日志输出位置,默认为FILE,即保存为文件,若设置为TABLE,则将日志记录到mysql。showlog表中,支持设置多种格式。 执行如下语句看是否启用了慢查询日志,ON为启用,OFF为未启用,默认为OFF。SHOWVARIABLESLIKEslowquerylog; 可以看到,我这里是已经开启了的。如果你的没有开启,可以使用如下两种方式来开启慢查询。2。1修改配置文件 修改配置文件vimetcmy。cnf,在〔mysqld〕段落在加入如下配置: 〔mysqld〕 slowquerylog1 slowquerylogfilevarlibmysqldataslow。log longquerytime3 logoutputFILE,TABLE 需要重启MySQL才可以生效,命令为servicemysqldrestart2。2设置全局变量 如下打开慢查询日志,设置超时时间为3秒,并且将日志记录到文件以及mysql。showlog表中。 SETGLOBALslowquerylog1; SETGLOBALslowquerylogfilevarlibmysqldataslow。log; SETGLOBALlongquerytime3; SETGLOBALlogoutputFILE,TABLE; 想要永久生效得用上面那个配置文件里配置,否则数据库重启后,这些配置失效。三、分析慢查询日志3。1获取慢SQL信息 查看慢查询日志记录数:SHOWGLOBALSTATUSLIKESlowqueries; 模拟语句:selectsleep(5); 查看日志:catvarlibmysqldataslow。log 3。2mysqldumpslow MySQL内置了mysqldumpslow这个工具来帮我们分析慢查询日志。 得到返回记录集最多的10个SQLmysqldumpslowsrt10varlibmysqldataslow。log得到访问次数最多的10个SQLmysqldumpslowsct10varlibmysqldataslow。log得到按照时间排序的前10条里面含有左连接的查询语句mysqldumpslowstt10gLEFTJOINvarlibmysqldataslow。log结合more使用,防止爆屏情况mysqldumpslowsrt10varlibmysqldataslow。logmores:表示按何种方式排序c:访问次数l:锁定时间r:返回记录t:查询时间al:平均锁定时间ar:平均返回记录数at:平均查询时间t:返回前面多少条的数据g:后边搭配一个正则匹配模式,大小写不敏感3。3ptquerydigest ptquerydigest是一款很强大的慢查询日志分析工具,可以分析MySQL数据库的binarylog、generallog日志,同时也可以使用showprocesslist或从tcpdump抓取的MySQL协议数据来进行分析。 这里老周不带大家搭建以及使用了哈,想进一步了解的可以看这份文档:ptquerydigest四、Explain执行计划分析慢SQL 上一篇我们非常详细的去介绍了,一文读懂MySQLExplain执行计划五、ShowProfile分析慢SQL ShowProfile也可以分析慢SQL,比explain获取的信息更详细,比如能分析当前会话中语句执行的资源消耗情况,能分析这条SQL整个生命周期的耗时。但没有上面ptquerydigest那款慢查询日志分析工具强大,但ptquerydigest是外置的需要单独下载,如果你想用内置的话,能够满足你的需求的话,选择ShowProfile就行。5。1如何开启 默认关闭。开启后,会在后台保存最近15次的运行结果,然后通过ShowProfile命令查看结果。开启SETprofilingON;查看SHOWVARIABLESLIKEprofiling; 5。2SHOWprofiles查看SQL的耗时 5。3SQL整个生命周期的耗时 通过QueryID可以得到具体SQL从连接服务引擎存储四层结构完整生命周期的耗时SHOWprofileCPU,BLOCKIOFORQUERY4; 在这里插入图片描述 可用参数type: ALL显示所有的开销信息 BLOCKIO显示块IO相关开销 CONTEXTSWITCHES上下文切换相关开销 CPU显示CPU相关开销信息 IPC显示发送和接收相关开销信息 MEMORY显示内存相关开销信息 PAGEFAULTS显示页面错误相关开销信息 SOURCE显示和Sourcefunction,Sourcefile,Sourceline相关的开销信息 SWAPS显示交换次数相关开销的信息5。4危险状态SHOWprofileCPU,BLOCKIOFORQUERY2; GROUPBY可能创建了临时表 危险状态: convertingHEAPtoMyISAM查询结果太大,内存不够用了,在往磁盘上搬。 Creatingtmptable创建了临时表,回先把数据拷贝到临时表,用完后再删除临时表。 Copyingtotmptableondisk把内存中临时表复制到磁盘 locked记录被锁了 看到这些危险状态可以进行相应的调优,然后我们线上也会针对慢SQL进行监控,存在慢SQL的话会触发告警机制,通知相应的人员快速定位慢SQL并优化。