SQL进阶理论篇(十五):数据库的慢查询定位

文章目录

  • 简介
  • 数据库服务器的优化步骤
  • 使用慢查询
  • 使用explain
  • 使用show profile
  • 参考文献

简介

本节的主要内容如下:

  • 数据库服务器的优化分析步骤是怎样的?
  • 如何用慢查询日志查找执行慢的SQL语句?
  • 如何使用explain查看SQL执行计划?
  • 如何使用show profiling分析SQL执行步骤中的每一步的执行时间?

数据库服务器的优化步骤

教程里给出了这么一张图:

SQL进阶理论篇(十五):数据库的慢查询定位_第1张图片

S1部分,需要观察服务器的状态是否是周期性的,比如说每个月固定几天慢,或者是每年固定几天慢这种。如果存在这种周期性的波动,那么可能是周期性业务节点的问题,比如说双十一等促销活动。这时候我们可以选择加缓存或者更改缓存失效策略来解决。

如果上一步并没有解决问题,或者是服务器的状态不是周期性的,那么进入S2这一步。

S2部分,需要开启慢查询,来帮助我们定位执行慢的SQL语句。其中,我们通过设置long_query_time这个参数来定义"慢"的阈值,如果 SQL的执行时间超过了这个阈值,就可以认为是慢查询,会被统一收集起来,做下一步分析。

S3部分,需要对执行慢的SQL语句做进一步分析。通过explain来查看对应的执行计划,通过show profile来查看每个步骤的时间成本。结合判断,查询慢是因为执行时间长,还是等待时间长。

如果是等待时间长,则进入A2步骤,调整服务器的参数,比如说适当扩大数据库缓冲池等。

如果是执行时间长,则进入A3步骤,考虑对SQL语句做优化(减少关联表等),或者对涉及到的表做优化(加索引)。

如果A2和A3都不能解决问题,那么可能是数据库自身的性能到瓶颈了,进入A4阶段,开始掏钱,看是否是需要增加服务器或者内存等,是否读写分离,是否分库分表等等。

以上就是数据库调优的完整流程思路,其实总结起来就是三个工具的使用:慢查询、explainshow profile

使用慢查询

慢查询,全称是慢查询日志,它可以帮助我们定位到执行慢的SQL。

使用前,我们需要查看慢查询是否已经开启:

mysql > show variables like '%slow_query_log';

在这里插入图片描述

OFF就是没开,可以通过以下方式打开:

mysql > set global slow_query_log='ON';

然后我们通过以下命令,查看慢查询日志文件的位置:

mysql > show variables like '%slow_query_log%';

在这里插入图片描述

慢查询里还有一个核心参数,即时间阈值参数,超过阈值的SQL查询才会被认为是慢查询,从而写进慢查询日志里。

可以使用下面命令来查看这个时间阈值参数:

mysql > show variables like '%long_query_time%';

在这里插入图片描述

默认情况下是10s,单位是秒。

可以通过下面命令进行修改:

mysql > set global long_query_time = 3;

即将时间修改为3s。

我们可以通过MySQL自带的mysqldumpslow这个工具来统计慢查询日志(是一个perl脚本,需要安装perl)。

只做下简单理解吧。

比如我们想要按照查询时间排序,查看前两条SQL语句,这样写即可:

perl mysqldumpslow.pl -s t -t 2 "慢查询日志路径"

-s t表示以查询时间来排序,-s支持多种排序参数,分别是 c(访问次数)、t(查询时间)、l(锁定时间)、r(返回记录)、ac(平均查询次数)、al(平均锁定时间)、ar(平均返回记录数)和 at(平均查询时间。

-t 2表示返回前两条数据。

了解即可。开启了慢查询日志,并设置了相应的慢查询时间阈值之后,只要查询时间大于这个阈值的 SQL 语句都会保存在慢查询日志中。

使用explain

之前其实也讲过,explain用来查看SQL的执行计划。

比如:

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 

这里不再详述。

使用show profile

show profile可以进一步看到更详细的解析,包括SQL优化用了多久、统计用了多久、查询用了多久等。

查看profiling是否开启,默认是关闭OFF的:

mysql > show variables like 'profiling';

通过下面指令开启:

mysql > set profiling = 'ON';

查看当前会话下有哪些profiling:

mysql > show profiles;

SQL进阶理论篇(十五):数据库的慢查询定位_第2张图片

可以看到当前会话一共有过两个查询,如果想查看最近一个查询的开销,可以使用:

mysql > show profile;

SQL进阶理论篇(十五):数据库的慢查询定位_第3张图片

或者查看指定Query ID的开销,比如说查看ID为2的查询的消耗:

show profile for query 2;

或者查看详细信息:

show profile cpu,block io for query 2;

SQL进阶理论篇(十五):数据库的慢查询定位_第4张图片

可以看到不同部分的开销,比如CPU、磁盘IO等。

我们可以根据每一部分的执行时间,来判断SQL到底慢在哪里。

不过,show profile在高版本中即将被弃用,我们现在也可以使用下面这种方式来代替:

select * from information_schema.profiling;

不过这种方式也需要提前将profiling打开,即执行set profiling = 'ON';

参考文献

  1. 33丨如何使用性能分析工具定位SQL执行慢的原因?

你可能感兴趣的:(#,SQL基础,数据库,sql)