SQL优化
如何从一个大项目中,迅速的定位执行速度慢的语句. (定位慢查询)
文件在:E:\学习文档子目录压缩\数据库\mysql\mysql优化\蚂蚁\蚂蚁1\1mysql优化之慢查询日志处理或 我的网盘\我的笔记\学习文档子目录压缩\数据库\mysql\mysql优化\蚂蚁\蚂蚁1\1mysql优化之慢查询日志处理
show status
使用show status使用show status查看MySQL服务器状态信息
常用命令
--mysql数据库启动了多少时间 show status like 'uptime'; |
show stauts like 'com_select' show stauts like 'com_insert' ...类推 update delete(显示数据库的查询,更新,添加,删除的次数) |
show [session|global] status like .... 如果你不写 [session|global] 默认是session 会话,指取出当前窗口的执行,如果你想看所有(从mysql 启动到现在,则应该 global) |
//显示到mysql数据库的连接数 show status like 'connections '; |
//显示慢查询次数 show status like 'slow_queries'; |
慢查询
什么是慢查询
MySQL默认10秒内没有响应SQL结果,则为慢查询
可以去修改MySQL慢查询默认时间
如何修改慢查询
--查询慢查询时间 show variables like 'long_query_time'; --修改慢查询时间 set long_query_time=1; ---但是重启mysql之后,long_query_time依然是my.ini中的值 |
如何定位慢查询
初始化测试数据
创建表结构
/*部门表*/ CREATE TABLE dept( deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, /*编号*/ dname VARCHAR(20) NOT NULL DEFAULT "", /*名称*/ loc VARCHAR(13) NOT NULL DEFAULT "" /*地点*/ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; /*员工表*/ CREATE TABLE emp (empno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, /*编号*/ ename VARCHAR(20) NOT NULL DEFAULT "", /*名字*/ job VARCHAR(9) NOT NULL DEFAULT "",/*工作*/ mgr MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,/*上级编号*/ hiredate DATE NOT NULL,/*入职时间*/ sal DECIMAL(7,2) NOT NULL,/*薪水*/ comm DECIMAL(7,2) NOT NULL,/*红利*/ deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 /*部门编号*/ )ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
/*薪水*/ CREATE TABLE salgrade ( grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, losal DECIMAL(17,2) NOT NULL, hisal DECIMAL(17,2) NOT NULL )ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*测试数据*/
INSERT INTO salgrade VALUES (1,700,1200); INSERT INTO salgrade VALUES (2,1201,1400); INSERT INTO salgrade VALUES (3,1401,2000); INSERT INTO salgrade VALUES (4,2001,3000); INSERT INTO salgrade VALUES (5,3001,9999); |
创建函数
create function rand_string(n INT) returns varchar(255) #该函数会返回一个字符串 begin #chars_str定义一个变量 chars_str,类型是 varchar(100),默认值'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'; 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
create FUNCTION rand_num() RETURNS int(5) BEGIN DECLARE i int default 0; set i =floor(10+RAND()*500); return i; END |
创建存储过程
delimiter $$ create procedure insert_emp(in start int(10),in max_num int(10)) begin declare i int default 0; #set autocommit =0 把autocommit设置成0 set autocommit = 0; repeat set i = i + 1; insert into emp values ((start+i) ,rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand_num()); until i = max_num end repeat; commit; end $$ 执行存储过程 call insert_emp (100001,4000000); |
如何将慢查询定位到日志中
在默认情况下,我们的mysql不会记录慢查询,需要在启动mysql时候,指定记录慢查询才可以
bin\mysqld.exe --safe-mode --slow-query-log [mysql5.5 可以在my.ini指定](安全模式启动,数据库将操作写入日志,以备恢复)
bin\mysqld.exe –log-slow-queries=d:/abc.log [低版本mysql5.0可以在my.ini指定]
先关闭mysql,再启动, 如果启用了慢查询日志,默认把这个文件放在
my.ini 文件中记录的位置
#Path to the database root
datadir=" C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
特别提醒,在安全模式启动 即在cmd中执行mysql安装目录 bin\mysqld.exe --safe-mode --slow-query-log(5.5以上版本)或
bin\mysqld.exe –log-slow-queries=d:/abc.log
之前,必须先在 服务中关闭mysql
总体步骤
1.建测试数据库,造400万伪数据(按上面步骤,建表,建函数,建存储过程,执行存储过程即可)
2. 在mysql安装文件中从my.ini从查出日志文件所在位置(datadir),删除原有日志文件如ib_logfile0等,然后先在服务中关闭mysql(一定要右键属性,停止,看到启动已经亮了才行),然后cmd mysql安全模式启动
注意 5.0的版本bin下只有 mysqld-nt.exe命令和5.8的mysqld.exe是一个意思,cmd看到如下表示安全模式已经成功
3.navicte中连接测试数据库,修改将MySQL默认10秒内(修改为1秒) 没有响应SQL结果,则为慢查询
--修改慢查询时间
set long_query_time=1; ---但是重启mysql之后,long_query_time依然是my.ini中的值
4. 执行如下慢查询语句,查400万数据 select * from emp;
show status like 'slow_queries';--显示慢查询次数
5.在 datadir=" C:/ProgramData/MySQL/MySQL Server 5.5/Data/"(my.ini从查出日志文件所在位置(datadir))
或abc.log 去看那条慢查询sql
慢查询日志文件为:PC-20190414IHSY-slow.log
bin\mysqld.exe, Version: 5.5.62-log (MySQL Community Server (GPL)). started with:
TCP Port: 3306, Named Pipe: (null)
Time Id Command Argument
# Time: 190929 17:59:28
# User@Host: root[root] @ localhost [127.0.0.1]
# Query_time: 6.909395 Lock_time: 0.000000 Rows_sent: 6679074 Rows_examined: 6679074
use yh;
SET timestamp=1569751168;
select * from emp;
可以看到 Query_time: 6.909395 查询时间为6.9秒 ,慢查询sql为select * from emp;
--修改慢查询时间
set long_query_time=1; ---但是重启mysql之后,long_query_time依然是my.ini中的值
show status like 'slow_queries';--显示慢查询次数