MYSQL调优1-发现慢查询

来源:互联网 发布:three.js天空盒制作 编辑:程序博客网 时间:2024/06/02 03:37

一、           发现慢查询


如何从一个大项目中,迅速的定位执行速度慢的语句,这是本章节将要解决的问题。

1.      慢查询的定义

怎样的查询才算是慢查询,有没有一个量化的标准呢?

慢查询定义

       慢查询是指执行时间超过慢查询时间的sql语句。

查看慢查询时间的方法

[plain] view plain copy
print?
  1. show variables like ‘long_query_time’;  
show variables like 'long_query_time';

可以显示当前慢查询时间。MySql默认慢查询时间为10秒


可以通过如下语句对慢查询的定义进行修改

[plain] view plain copy
print?
  1. set global long_query_time=1;  
set global long_query_time=1;


(如果你的mysql设置了缓存,那么需要重新进入命令行窗口才会查出变化)

需要注意的是,这个语句特意在变量前加上了global,表明这次的设置是对整个Mysql有效的,而默认情况下变量前的修饰符是session(会话),也就是只对当前窗口有效。


这一讲只是开个头,下一讲,我们会为慢查询的发生准备数据,即创建一张大表。

2. 慢查询数据准备

要想发现慢查询,首先要使慢查询发生。在一张普通数量级的表格中是不能发生慢查询的,除非你对于慢查询的定义时一个毫秒。因此我们必须手动创建一张大数量级的表,这里选择创建一张40万数量级的表(同学们也可以创建百万级的,如果你们的电脑很厉害。但是一般情况下,十万级的数据就可以看出慢查询了)。

1) 创建数据库

Create database bigTable default character set GBK;  

2) 创建表
部门表

CREATE TABLE dept(id int unsigned primary key auto_increment,deptno MEDIUMINT   UNSIGNED  NOT NULL  DEFAULT 0, dname VARCHAR(20)  NOT NULL  DEFAULT "",loc VARCHAR(13) NOT NULL DEFAULT "") ENGINE=INNODB DEFAULT CHARSET=GBK ;

雇员表

CREATE TABLE emp(id int unsigned primary key auto_increment,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=INNODB DEFAULT CHARSET=GBK ;

3) 创建函数
函数用于随机产生数据,保证每条数据都不同
函数1 创建#
创建函数. 用于随机产生字符串。该函数接收一个整数

delimiter $$#定义一个新的命令结束符合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 $$

函数2创建
用于随机产生部门编号

create function rand_num( )returns int(5)begin  declare i int default 0; set i = floor(10+rand()*500);return i;  end $$

4) 创建存储过程

存储过程一#
该存储过程用于往emp表中插入大量数据

create procedure insert_emp(in start int(10),in max_num int(10))begindeclare i int default 0; #set autocommit =0 把autocommit设置成0 set autocommit = 0;   repeat set i = i + 1; insert into emp (empno, ename ,job ,mgr ,hiredate ,sal ,comm ,deptno ) values ((start+i) ,rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand_num());  until i = max_num end repeat;   commit; end $$

执行存储过程,往emp表添加40万条数据

call insert_emp(100001,400000);  

查询,发现Emp表插入了40万条记录
存储过程二#
往dept表添加随机数据

create procedure insert_dept(in start int(10),in max_num int(10))begindeclare i int default 0;  set autocommit = 0;   repeat set i = i + 1; insert into dept (deptno ,dname,loc  ) values ((start+i) ,rand_string(10),rand_string(8));  until i = max_num end repeat;   commit; end $$

执行存储过程二

delimiter ;  call insert_dept(100,10);  

3.      记录慢查询


此时我们已经有让慢查询发生的成本了。执行以下语句,你就知道什么叫慢!查!询!

select empno from emp where ename='';


一个很明显找不到结果的查询语句居然也执行了近3秒钟。

这时候,作为DBA就应该把这个sql语句记录下来,是记在记事本还是写在笔记本呢?不用想太多了,不用你自己记,MySQL提供了慢查询日志功能,自动帮你记录慢查询的语句。

1)    把慢查询的sql记录到日志中

首先你要打开慢查询日志文件记录器

使用

show variables like 'slow%';

你会发现默认情况下慢查询日志记录器关闭的

使用

set global slow_query_log=ON;

打开之



此时你会发现mysql安装目录下的data文件夹中出现了以你本机名命名的日志文件


此时再执行慢查询操作


打开日志文件发现出现记录


以后只需要定期检查日志文件就可以找到慢查询语句了


注意:

在找到慢查询语句后,要通过反复使用select语句确认慢查询,注意只能使用select语句,就算是原来语句为delete或者update等,也要用select代替,因为只有select不会弄脏数据库


2)    另一种发现慢查询语句的方法

要是你使用hibernate进行J2ee开发,可以使用一下方式。

在页面中进行操作,当发现某个操作的响应较慢时,查看Eclipse控制台的Hibernate输出sql语句,此语句即为慢查询语句。

0 0
原创粉丝点击