整个流程划分成了 观察(Show status) 和 行动(Action) 两个部分。字母 S 的部分代表观察(会使 用相应的分析工具),字母 A 代表的部分是行动(对应分析可以采取的行动)。
2. 查看系统性能参数
在MySQL中,可以使用 SHOW STATUS 语句查询一些MySQL数据库服务器的性能参数 、 执行频率。 SHOW STATUS语句语法如下:
mysql复制代码
SHOW [GLOBAL|SESSION] STATUS LIKE '参数';
一些常用的性能参数如下:
Connections:连接MySQL服务器的次数。
Uptime:MySQL服务器的上 线时间。
Slow_queries:慢查询的次数。
Innodb_rows_read:Select查询返回的行数
Innodb_rows_inserted:执行INSERT操作插入的行数
Innodb_rows_updated:执行UPDATE操作更新的 行数
Innodb_rows_deleted:执行DELETE操作删除的行数
Com_select:查询操作的次数。
Com_insert:插入操作的次数。对于批量插入的 INSERT 操作,只累加一次。
Com_update:更新操作 的次数。
Com_delete:删除操作的次数。
举例:
mysql复制代码
mysql> show status like 'connections';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Connections | 21 |
+---------------+-------+
1 row in set (0.00 sec)
举例:
mysql复制代码
mysql> show status like 'uptime';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Uptime | 28235 |
+---------------+-------+
1 row in set (0.00 sec)
mysql复制代码
mysql> show status like 'slow_queries';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Slow_queries | 0 |
+---------------+-------+
1 row in set (0.00 sec)
CREATE TABLE `student_info` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`student_id` INT NOT NULL ,
`name` VARCHAR(20) DEFAULT NULL,
`course_id` INT NOT NULL ,
`class_id` INT(11) DEFAULT NULL,
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
如果我们想要查询 id=900001 的记录,然后看下查询成本,我们可以直接在聚簇索引上进行查找:
mysql复制代码
mysql> SELECT student_id, class_id, NAME, create_time FROM student_info WHERE id = 900001;
+------------+----------+--------+---------------------+
| student_id | class_id | NAME | create_time |
+------------+----------+--------+---------------------+
| 46284 | 10136 | gUfQOy | 2025-02-13 12:48:08 |
+------------+----------+--------+---------------------+
1 row in set (0.00 sec)
然后再看下查询优化器的成本,实际上我们只需要检索一个页即可:
mysql复制代码
mysql> SHOW STATUS LIKE 'last_query_cost';
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| Last_query_cost | 1.000000 |
+-----------------+----------+
1 row in set (0.00 sec)
如果我们想要查询 id 在 900001 到 9000100 之间的学生记录呢?
mysql复制代码
mysql> SELECT student_id, class_id, NAME, create_time FROM student_info WHERE id BETWEEN 900001 AND 900100;
运行结果(100 条记录,运行时间为 0.046s ):
然后再看下查询优化器的成本,这时我们大概需要进行 20 个页的查询。
mysql复制代码
mysql> SHOW STATUS LIKE 'last_query_cost';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| Last_query_cost | 20.290412 |
+-----------------+-----------+
1 row in set (0.00 sec)
#测试发现:设置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%';
4.2 查看慢查询数目
查询当前系统中有多少条慢查询记录
mysql复制代码
mysql> SHOW GLOBAL STATUS LIKE '%Slow_queries%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Slow_queries | 0 |
+---------------+-------+
1 row in set (0.00 sec)
set global log_bin_trust_function_creators=1; # 不加global只是当前窗口有效。
第2步:创建模拟数据必需的存储函数
说明: 创建函数,假如报错:
sh复制代码
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
#函数1:创建随机产生字符串函数
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 ;
mysql复制代码
#函数2:创建随机数函数
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;
第3步:创建插入模拟数据的存储过程
mysql复制代码
# 存储过程1:创建插入课程表存储过程
DELIMITER //
CREATE PROCEDURE insert_course( max_num INT )
BEGIN
DECLARE i INT DEFAULT 0;
SET autocommit = 0; #设置手动提交事务
REPEAT #循环
SET i = i + 1; #赋值
INSERT INTO course (course_id, course_name ) VALUES (rand_num(10000,10100),rand_string(6));
UNTIL i = max_num
END REPEAT;
COMMIT; #提交事务
END //
DELIMITER;
mysql复制代码
# 存储过程2:创建插入学生信息表存储过程
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 ;
mysql> show variables like 'min%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| min_examined_row_limit | 0 |
+------------------------+-------+
1 row in set (0.01 sec)
mysqldumpslow -s t -t 5 /var/lib/mysql/RainbowSea-slow.log
其中的路径位置是通过如下:show variables like '%slow_query_log%';这条命令查询到的
mysql复制代码
mysql> show variables like '%slow_query_log%';
+---------------------+------------------------------------+
| Variable_name | Value |
+---------------------+------------------------------------+
| slow_query_log | ON |
| slow_query_log_file | /var/lib/mysql/RainbowSea-slow.log |
+---------------------+------------------------------------+
2 rows in set (0.01 sec)
sh复制代码
[root@RainbowSea ~]# mysqldumpslow -s t -t 5 /var/lib/mysql/RainbowSea-slow.log
Reading mysql slow query log from /var/lib/mysql/RainbowSea-slow.log
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows=0.0 (0), 0users@0hosts
工作常用参考:
sh复制代码
#得到返回记录集最多的10个SQL
mysqldumpslow -s r -t 10 /var/lib/mysql/RainbowSea-slow.log
#得到访问次数最多的10个SQL
mysqldumpslow -s c -t 10 /var/lib/mysql/RainbowSea-slow.log
#得到按照时间排序的前10条里面含有左连接的查询语句
mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/RainbowSea-slow.log
#另外建议在使用这些命令时结合 | 和more 使用 ,否则有可能出现爆屏情况
mysqldumpslow -s r -t 10 /var/lib/mysql/RainbowSea-slow.log | more
4.6 关闭慢查询日志
MySQL服务器停止慢查询日志功能有两种方法:
方式1:永久性方式 通过 mysql 配置文件etc/my.ini
properties复制代码
[mysqld]
slow_query_log=OFF
或者,把slow_query_log一项注释掉 或 删除
properties复制代码
[mysqld]
#slow_query_log =OFF
重启MySQL服务,执行如下语句查询慢日志功能。
mysql复制代码
SHOW VARIABLES LIKE '%slow%'; #查询慢查询日志所在目录
SHOW VARIABLES LIKE '%long_query_time%'; #查询超时时长
方式2:临时性方式
使用SET语句来设置。 (1)停止MySQL慢查询日志功能,具体SQL语句如下。
mysql复制代码
SET GLOBAL slow_query_log=off;
(2)重启MySQL服务,使用SHOW语句查询慢查询日志功能信息,具体SQL语句如下
sh复制代码
SHOW VARIABLES LIKE '%slow%';
#以及
SHOW VARIABLES LIKE '%long_query_time%';
4.7 删除慢查询日志
进入到我们的日志文件的目录当中,找到对于的日志文件,然后,直接删除就可以了。
通过如下指令:找到日志文件的所在位置
mysql复制代码
mysql> show variables like '%slow_query_log%';
+---------------------+------------------------------------+
| Variable_name | Value |
+---------------------+------------------------------------+
| slow_query_log | ON |
| slow_query_log_file | /var/lib/mysql/RainbowSea-slow.log |
+---------------------+------------------------------------+
2 rows in set (0.01 sec)
从执行结果可以看出,慢查询日志的目录默认为 MySQL 的数据目录,在该目录下手动删除慢查询日志文件 即可。使用命令mysqladmin flush-logs 来重新生成查询日志文件,具体命令如下,执行完毕会在数据目录下重新生成慢查询日志文件。