mysql慢查询日志开启

mysql 提供一种慢查询日志记录,用于记录响应时间超过阈值的SQL语句(默认是关闭的)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
临时开启:
mysql> show variables like '%slow_query_log%';
+---------------------+-----------------------------------------------+
| Variable_name | Value |
+---------------------+-----------------------------------------------+
| slow_query_log | OFF |
| slow_query_log_file | /home/WDPM/MysqlData/mysql/DB-Server-slow.log |
+---------------------+-----------------------------------------------+
2 rows in set (0.00 sec)

mysql> set global slow_query_log=1;
Query OK, 0 rows affected (0.09 sec)

mysql> show variables like '%slow_query_log%';
+---------------------+-----------------------------------------------+
| Variable_name | Value |
+---------------------+-----------------------------------------------+
| slow_query_log | ON |
| slow_query_log_file | /home/WDPM/MysqlData/mysql/DB-Server-slow.log |
+---------------------+-----------------------------------------------+
2 rows in set (0.00 sec)

mysql>
1
2
3
4
5
6
7
永久开启,在my.cnf中加入配置:
[mysqld]
...
slow_query_log=1
long_query_time=3 设置阈值,单位秒
slow_query_log_file=/var/lib/mysql/localhost_slow.log
...

排查慢查询

查询慢查询数量

一般来说,每分钟慢查询在个位数是正常的,如果量比较大,就可能存在问题
慢查询的数量保存在mysql库里面的slow_log表。
select * from slow_log where start_time > '2021-11-01 00:00:00'

查看当前进行的查询状态

查看当前系统的查询,可以试用show processlist,如果要做条件查询,则可以直接查询information_schema库里面的processlist表
查看当前所有process:
select * from information_schema.processlist
查看当前正在进行的查询并按照已经执行时间倒排
select * from information_schema.processlist where info is not null order by time desc
一般来讲,一条查询的执行速度很快,所以被我们抓到info不是null的数量不会太多,一般几条,如果一次查到info不是null的数量较多,可能就是系统出了问题。

问题定位与解决

当察觉系统变慢时,查询慢查询数量以及查看processlist,看慢查询数量是不是飙升,processlist中是不是很多lock状态,或者执行了很长时间的查询。为了尽快恢复系统的正常运行,直接kill掉那些lock和执行较长时间的查询,但这是临时的办法,我们还要找到慢查询的原因。
mysql> kill id
在慢查询表里有几个比较重要的指标:

  • start_time 开始时间,通过这个参数配合系统出现问题的时间,定位是哪些查询造成的
  • query_time 查询时间
  • rows_sent 发送的结果数
  • rows_examined 查询扫过的行数,通过这个参数基本可以告诉我们,那个是大查询
    在实际操作中,需要把row_examined较大的查询拿出来做优化,添加索引,修改语句等来彻底解决问题。

explain分析SQL执行状态

explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。

使用方法,在select语句前加上explain就可以了,例如下:

explain select c.title, cc.content form comment_content cc, comment c where cc.id=c.id

explain列解释
  • table列:显示这一行的数据是关于哪张表的

  • type列:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、index和ALL

  • possible_keys 列:显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择一个合适的语句

  • key列:实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MYSQL会选择优化不足的索引。这种情况下,可以在SELECT语句 中使用USE INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MYSQL忽略索引

  • key_len列:使用的索引的长度。在不损失精确性的情况下,长度越短越好

  • ref列:显示索引的哪一列被使用了,如果可能的话,是一个常数

  • rows列:MYSQL认为必须检查的用来返回请求数据的行数

  • Extra列:关于MYSQL如何解析查询的额外信息。

SQL优化建议

  • 优化索引,最简单粗暴的办法,给查询语句添加复合索引,但不是最好的方式
  • 将大表拆成小的汇总表
  • 避免在大表上的group by,order by,offset 操作,除非你知道如何优化的前提下
  • SQL WHERE查询条件,尽量按照添加的索引顺序来写