Mysql之慢查询的排查及其优化

Posted 天天向上的菜鸡杰!!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql之慢查询的排查及其优化相关的知识,希望对你有一定的参考价值。

文章目录


一:建造海量数据插入数据库

1:建造表

CREATE TABLE `t_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` tinyint(4) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2:插入200万条数据

delimiter $$
DROP PROCEDURE IF EXISTS proc_batch_insert;
CREATE PROCEDURE proc_batch_insert()
BEGIN
DECLARE pre_name BIGINT;
DECLARE ageVal INT;
DECLARE i INT;
SET pre_name=187635267;
SET ageVal=100;
SET i=1;
WHILE i < 1000000 DO
		INSERT INTO t_user(`name`,age,create_time,update_time) VALUES(CONCAT(pre_name,'@qq.com'),(ageVal+i)%30,NOW(),NOW());
SET pre_name=pre_name+100;
SET i=i+1;
END WHILE;
END $$

delimiter ;
call proc_batch_insert();

二:排查慢查询的sql

前言:

我们查询比较慢的sql我们一定要将其记录下来 记录我们执行的sql 这样们在排查的时候才可以记录下来,那么我们可以打开我们的mysql慢查询日志,在这个日志里会记录下我们慢查询的sql 当然这个慢查询日志中的慢查询是有限定时间的,我们可以更改限定时间

1:查看数据库服务慢查询日志是否开启

show variables like 'slow_query_log';


默认 是关闭的 我们选择打开

2:开启慢查询日志

set global slow_query_log=on;

3:查看慢查询阈值(超过这个时间sql就会被记录在慢查询日志中)

这个阈值默认是10s

show variables like 'long_query_time’;

4:我们更改一下阈值(因为我们的测试数据插叙时间基本上是不会超过10s的)

set long_query_time=0.3;

5:查看慢查询日志的位置

主要是方便我们后续进行查找

show variables like 'slow_query_log_file';

6:测试慢查询的sql

(1):测试用例一

select * from t_user;

(2):测试用例二

SELECT
	id,NAME,
	age 
FROM
	t_user 
where name = '187795367@qq.com';

7:查询慢SQL的日志

注意Mac电脑的话 你是无权限打开 data 文件夹的 也就是无法查看你的mysql日志 所以需要开权限 :sudo chmod -R 777 文件路径

 cat MacdeMacBook-Pro-slow.log


这里显示出我们慢查询的两条sql 数据 同时显示出了慢sql的执行语句 以及 慢sql的执行时间(超过我们设置的0.3s的才记录下来)同时还显示出了查询的行数;找出这些SQL语句并不意味着完事了,些时我们常常用到explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描,这都可以通过explain命令来查看。

小结:

mysql判断sql语句是不是慢查询,是根据语句的执行时间来衡量的,mysql会用语句的执行时间和long_query_time这个系统参数做比较,如果语句执行时间大于long_query_time,都会把这个语句记录到慢查询日志里面。long_query_time的默认值是10s,一般生产环境不会设置这么大的值,一般设置1秒

三:慢查询优化

前言:

找出这些SQL语句并不意味着完事了,些时我们常常用到explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描,这都可以通过explain命令来查看。

1:查询sql的执行计划

EXPLAIN SELECT
	id,NAME,
	age 
FROM
	t_user 
where name = '187795367@qq.com';


为了直观展示查询结果,这里使用navicat执行sql。
主要看type那列,ALL标识全文检索,所以这条sql查询很慢。
解决:最简单有效的方法就是:加索引。

2:加索引

alter table add index nameIndex (name);


可以看出type是ref,已经不是全盘扫描了。

再进行查询

SELECT
	id,NAME,
	age 
FROM
	t_user 
where name = '187795367@qq.com';

3.索引时间进行比较

  • 没加索引之前0.4s
  • 加索引之后0.01s
    很明显快了几十倍。

4:小结

MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。
创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。

Mysql优化之慢查询优化

1、什么是慢查询?

慢查询顾名思义,就是查询慢的sql日志,是指Mysql记录所有执行时间超过long_query_time参数设定的时间阈值SQL语句的日志。该日志能为SQL语句的优化带来很好的帮助,能够帮助你更快速的定位执行慢的SQL语句。

默认情况下,慢查询是关闭的,要使用慢查询日志功能,首先要开启慢查询日志功能。

2、慢查询怎么启动?

找到my.ini(linux找到my.cnf)配置文件,增加慢查询配置

技术图片

 配置好上述内容,重启MySql加载配置。

通过下面语句查询是否配置生效:

show VARIABLES like ‘%slow_query_log%‘
show VARIABLES like ‘%slow_query_log_file%‘
show VARIABLES like ‘%long_query_time%‘
show VARIABLES like ‘%log_queries_not_using_indexes%‘
show VARIABLES like ‘log_output‘

3、慢查询场景解读

(1) 先设置SQL执行时间伐值为1s

set global long_query_time=1

技术图片

(2) 随便查询一张表,查询时间大于1s即可

(3) 去查看配置好的日志输出路径就会发现

技术图片

 

(4) 文件内容解读

技术图片

第一行 Time:记录的是一个语句的执行时间

第二行 分别是用户名、用户的ip信息、线程id

第三行 Query_time:执行语句花费的时间, Lock_time:执行获得锁的时间,Rows_sent:获得的结果行数,Rows_examined:扫描的数据行数

第四行 SQL语句执行的具体时间

第五行 具体的SQL语句

PS:慢查询的日志记录非常多,要从里面找寻一条查询慢的日志并不是很容易的事情,需要一些工具辅助才能够快速定位需要优化的语句,可以使用Mysqldumpslow来分析

 

以上是关于Mysql之慢查询的排查及其优化的主要内容,如果未能解决你的问题,请参考以下文章

MySQL优化之慢日志分析(Anemometer+Pt-query-digest)

逆水行舟 —— SQL优化之慢查询和explain以及性能分析

MySQL之慢查询日志分析

mysql 开发进阶篇系列 41 mysql日志之慢查询日志

记一次mysql查询慢的优化历程

MySQL之慢查询日志