mysql中慢查询问题解决思路

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

1.开启慢查询日志参数

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

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

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

mysql中慢查询问题解决思路_第1张图片

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

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

mysql中慢查询问题解决思路_第2张图片

你能看到这时慢查询分析已经开启,同时文件保存在 /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%';

mysql中慢查询问题解决思路_第3张图片

#测试发现:设置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%';

mysql中慢查询问题解决思路_第4张图片

查看慢查询数目

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

案例演示

步骤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

mysql中慢查询问题解决思路_第5张图片

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

你可能感兴趣的:(sql学习,sql,mysql)