定位执行慢的 SQL:慢查询日志

1.开启慢查询日志参数

我们再来查看下慢查询日志是否开启,以及慢查询日志文件的位置:

执行这个命令:show variables like '%slow_query_log%';

通常情况下这个结果的执行结果如下:

可以看到,这里的慢查询日志是关闭的。

执行这个命令:set global slow_query_log='ON';

你能看到这时慢查询分析已经开启,同时文件保存在 /var/lib/mysql/atguigu02-slow.log 文件中。

2. 修改long_query_time阈值

接下来我们来看下慢查询的时间阈值设置,使用如下命令:

这里如果我们想把时间缩短,比如设置为 1 秒,可以这样设置:

mysql > set global slow_query_log='ON'; mysql > show variables like '%long_query_time%';

#测试发现:设置global的方式对当前session的long_query_time失效。对新连接的客户端有效。所以可以一并

执行下述语句

mysql > set global long_query_time = 1;

mysql> show global variables like '%long_query_time%';

mysql> set long_query_time=1; mysql> show variables like '%long_query_time%';

查看慢查询数目

查询当前系统中有多少条慢查询记录

案例演示

步骤1. 建表

CREATE TABLE `student` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `stuno` INT NOT NULL , `name` VARCHAR(20) DEFAULT NULL, `age` INT(3) DEFAULT NULL, `classId` INT(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

步骤2:设置参数 log_bin_trust_function_creators

创建函数,假如报错:

This function has none of DETERMINISTIC......

命令开启:允许创建函数设置:

set global log_bin_trust_function_creators=1; # 不加global只是当前窗口有效。

步骤3:创建函数

随机产生字符串:

DELIMITER //

CREATE FUNCTION rand_string(n INT)

RETURNS VARCHAR(255) #该函数会返回一个字符串

BEGIN

DECLARE chars_str VARCHAR(100) DEFAULT

'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';

DECLARE return_str VARCHAR(255) DEFAULT '';

DECLARE i INT DEFAULT 0;

WHILE i < n DO

SET return_str =CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));

SET i = i + 1;

END WHILE;

RETURN return_str;

END //

DELIMITER ;

#测试

SELECT rand_string(10);

产生随机数值:

DELIMITER //

CREATE FUNCTION rand_num (from_num INT ,to_num INT) RETURNS INT(11)

BEGIN

DECLARE i INT DEFAULT 0;

SET i = FLOOR(from_num +RAND()*(to_num - from_num+1)) ;

RETURN i;

END //

DELIMITER ;

#测试:

SELECT rand_num(10,100);

步骤4:创建存储过程

DELIMITER //

CREATE PROCEDURE insert_stu1( START INT , max_num INT )

BEGIN

DECLARE i INT DEFAULT 0;

SET autocommit = 0; #设置手动提交事务

REPEAT #循环

SET i = i + 1; #赋值

INSERT INTO student (stuno, NAME ,age ,classId ) VALUES

((START+i),rand_string(6),rand_num(10,100),rand_num(10,1000));

UNTIL i = max_num

END REPEAT;

COMMIT; #提交事务

END //

DELIMITER ;

步骤5:调用存储过程

# 调用刚刚写好的函数, 4000000条记录,从100001号开始

CALL insert_stu1(100001,4000000);

测试及分析

1. 测试

mysql> SELECT * FROM student WHERE stuno = 3455655;

+---------+---------+--------+------+---------+

| id | stuno | name | age | classId |

+---------+---------+--------+------+---------+

| 3523633 | 3455655 | oQmLUr | 19 | 39 |

+---------+---------+--------+------+---------+

1 row in set (2.09 sec)

mysql> SELECT * FROM student WHERE name = 'oQmLUr';

+---------+---------+--------+------+---------+

| id | stuno | name | age | classId |

+---------+---------+--------+------+---------+

| 1154002 | 1243200 | OQMlUR | 266 | 28 |

| 1405708 | 1437740 | OQMlUR | 245 | 439 |

| 1748070 | 1680092 | OQMlUR | 240 | 414 |

| 2119892 | 2051914 | oQmLUr | 17 | 32 |

| 2893154 | 2825176 | OQMlUR | 245 | 435 |

| 3523633 | 3455655 | oQmLUr | 19 | 39 |

+---------+---------+--------+------+---------+

6 rows in set (2.39 sec)

从上面的结果可以看出来,查询学生编号为“3455655”的学生信息花费时间为2.09秒。查询学生姓名为

“oQmLUr”的学生信息花费时间为2.39秒。已经达到了秒的数量级,说明目前查询效率是比较低的,下面

的小节我们分析一下原因。

2. 分析

show status like 'slow_queries';

慢查询日志分析工具:mysqldumpslow

在生产环境中,如果要手工分析日志,查找、分析SQL,显然是个体力活,MySQL提供了日志分析工具:mysqldumpslow 。

查看mysqldumpslow的帮助信息

mysqldumpslow --help

mysqldumpslow 命令的具体参数如下:

-a: 不将数字抽象成N,字符串抽象成S

-s: 是表示按照何种方式排序:

c: 访问次数

l: 锁定时间

r: 返回记录

t: 查询时间

al:平均锁定时间

ar:平均返回记录数

at:平均查询时间 (默认方式)

ac:平均查询次数

-t: 即为返回前面多少条的数据;

6 rows in set (2.39 sec)

show status like 'slow_queries';

mysqldumpslow --help-g: 后边搭配一个正则匹配模式,大小写不敏感的;

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

mysqldumpslow -s t -t 5 /var/lib/mysql/atguigu01-slow.log

[root@bogon ~]# mysqldumpslow -s t -t 5 /var/lib/mysql/atguigu01-slow.log

Reading mysql slow query log from /var/lib/mysql/atguigu01-slow.log

Count: 1 Time=2.39s (2s) Lock=0.00s (0s) Rows=13.0 (13), root[root]@localhost

SELECT * FROM student WHERE name = 'S'

Count: 1 Time=2.09s (2s) Lock=0.00s (0s) Rows=2.0 (2), root[root]@localhost

SELECT * FROM student WHERE stuno = N

Died at /usr/bin/mysqldumpslow line 162, <> chunk 2.

工作常用参考:

         

#得到返回记录集最多的10个SQL

mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log

#得到访问次数最多的10个SQL

mysqldumpslow -s c -t 10 /var/lib/mysql/atguigu-slow.log

#得到按照时间排序的前10条里面含有左连接的查询语句

mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/atguigu-slow.log

#另外建议在使用这些命令时结合 | 和more 使用 ,否则有可能出现爆屏情况

mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log | more

推荐文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: