MySQL数据库优化技术之SQL语句慢查询定位
通过show status命令了解各种SQL的执行频率
MySQL客户端连接成功后,通过使用show [session|global] status 命令可以提供服务器状态信息;
其中的session来表示当前的连接的统计结果,global来表示自数据库启动至今的统计结果,默认是session级别的。
show status 常用命令:
show status like 'com_%';
其中com_xxx表示xxx语句所执行的次数;
重点注意com_select, com_insert, com_update, com_delete通过这几个参数,可以容易的了解到当前数据库应用是以插入更新为主还是以查询为主(来决定不同的存储引擎),以及各类的SQL大致执行比例是多少。
show status like 'com_insert';
show status like 'com_delete';
show status like 'com_update';
show status like 'com_select';
show status like 'connections'; //连接到MySQL服务器的连接数
show status like 'uptime'; //服务器的工作时间(单位:s)
show status like 'slow_queries'; //慢查询的次数(默认是慢查询时间:10S):不仅是查询,insert也包括的
如何定位慢查询(执行效率低)的SQL语句
默认情况下,MySQL认为10秒才是一个慢查询。
mysql> show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
set long_query_time=1; //修改mysql慢查询时间
mysql> set long_query_time=1;
Query OK, 0 rows affected (0.00 sec) mysql> show variables like 'long_query_time';
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| long_query_time | 1.000000 |
+-----------------+----------+
注意:set只对本MySQL Client有效。当打开一个新的客户端的时候,还是默认值10秒。
也可以在my.ini中进行配置,就会全局有效:
long_query_time=1
构建一个大表(400W)用于测试mysql优化语句:
#创建表DEPT
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 ; #创建表EMP雇员
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); # 随机产生字符串
#定义一个新的命令结束符合
delimiter $$
#删除自定的函数
drop function rand_string $$ #这里创建了一个函数.
#rand_string(n INT) rand_string 是函数名 (n INT) //该函数接收一个整数
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 $$ delimiter ;
select rand_string(6); # 随机产生部门编号
delimiter $$
drop function rand_num $$ #这里我们又自定了一个函数
create function rand_num( )
returns int(5)
begin
declare i int default 0;
set i = floor(10+rand()*500);
return i;
end $$ delimiter ;
select rand_num(); #******************************************
#向emp表中插入记录(海量的数据) delimiter $$
drop procedure insert_emp $$ #随即添加雇员[光标] 400w
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 $$ delimiter ;
#调用刚刚写好的函数, 1800000条记录,从100001号开始
call insert_emp(100001,4000000); select count(*) from emp;
#4000000 #**************************************************************
# 向dept表中插入记录 delimiter $$
drop procedure insert_dept $$ create procedure insert_dept(in start int(10),in max_num int(10))
begin
declare i int default 0;
set autocommit = 0;
repeat
set i = i + 1;
insert into dept values ((start+i) ,rand_string(10),rand_string(8));
until i = max_num
end repeat;
commit;
end $$ delimiter ;
call insert_dept(100,10); #------------------------------------------------
#向salgrade 表插入数据
delimiter $$
drop procedure insert_salgrade $$
create procedure insert_salgrade(in start int(10),in max_num int(10))
begin
declare i int default 0;
set autocommit = 0;
ALTER TABLE emp DISABLE KEYS;
repeat
set i = i + 1;
insert into salgrade values ((start+i) ,(start+i),(start+i));
until i = max_num
end repeat;
commit;
end $$
delimiter ;
#测试不需要了
#call insert_salgrade(10000,1000000);
#----------------------------------------------
事先将long_query_time设置为1
mysql> select * from emp where empno=234567;
+--------+--------+----------+-----+------------+---------+--------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+--------+--------+----------+-----+------------+---------+--------+--------+
| 234567 | fgqmkp | SALESMAN | 1 | 2014-09-23 | 2000.00 | 400.00 | 444 |
+--------+--------+----------+-----+------------+---------+--------+--------+
1 row in set (8.09 sec)
总共花费了8.09秒
mysql> show status like 'slow_queries';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Slow_queries | 2 |
+---------------+-------+
1 row in set (0.00 sec)
为什么是2???其实统计的并不只是select,前面通过存储过程插入数据也算。
将慢查询的sql记录到我们的一个日志中
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服务并启动:bin\mysqld.exe --safe-mode --slow-query-log
如果启用了慢查询日志,默认把这个文件放在my.ini 文件中记录的位置: datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
下创建了一个:hostname-slow.log的文件
由于重启了mysql服务,为了测试,则需要重新设置慢查询时间:set long_query_time=1;
mysql> select * from emp where empno=234567;
+--------+--------+----------+-----+------------+---------+--------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+--------+--------+----------+-----+------------+---------+--------+--------+
| 234567 | fgqmkp | SALESMAN | 1 | 2014-09-23 | 2000.00 | 400.00 | 444 |
+--------+--------+----------+-----+------------+---------+--------+--------+
1 row in set (8.01 sec)
那么在hostname-show.log文件中就记录下了如下慢查询信息:
# Time: 140923 22:06:13
# User@Host: root[root] @ localhost [127.0.0.1]
# Query_time: 8.011458 Lock_time: 0.037002 Rows_sent: 1 Rows_examined: 4000000
use mysqltest;
SET timestamp=1411481173;
select * from emp where empno=234567;
当第二次执行相同的sql语句时,速度会快很多。
MySQL数据库优化技术之SQL语句慢查询定位的更多相关文章
- Mysql数据库优化技术之配置篇、索引篇 ( 必看 必看 转)
转自:Mysql数据库优化技术之配置篇.索引篇 ( 必看 必看 ) (一)减少数据库访问对于可以静态化的页面,尽可能静态化对一个动态页面中可以静态的局部,采用静态化部分数据可以生成XML,或者文本文件 ...
- Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句 # python3 # author lizm # datetime 2018-02-01 10:00:00 # -*- co ...
- MySQL的EXPLAIN命令用于SQL语句的查询执行计划
MySQL的EXPLAIN命令用于SQL语句的查询执行计划(QEP).这条命令的输出结果能够让我们了解MySQL 优化器是如何执行SQL 语句的.这条命令并没有提供任何调整建议,但它能够提供重要的信息 ...
- 如何找出MySQL数据库中的低效SQL语句
面对业务的迅猛发展,DBA的一项重要工作就是及时发现数据库中的低效SQL语句,有的可以立刻着手解决(比如缺少合适的索引),有的需要尽快反馈给开发人员进行修改. MySQL数据库有几个配置选项可以帮助我 ...
- Mysql性能优化一:SQL语句性能优化
这里总结了52条对sql的查询优化,下面详细来看看,希望能帮助到你 1, 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2,应尽量避免在 w ...
- MySQL数据库优化技术概述
对于一个以数据库为中心的应用,数据库的优化直接影响到程序的性能,因此数据库性能至关重要.一般来说,要保证数据库的效率,要做好以下几个方面的工作: 1. 数据库表设计: 表的设计合理化(符合3NF): ...
- Django中使用mysql数据库并使用原生sql语句操作
Django自身默认使用sqlite3这个轻量级的数据库,但是当我们开发网站时,sqlite3就没有mysql好,sqlite3适合一些手机上开发使用的数据库. 准备的软件mysql数据库,版本5.7 ...
- mysql数据库表的基本操作sql语句总结
1,命令行登录命令 mysql -h localhost -u root -p C:\Users\lenovo>mysql -u root -p Enter password: ***** We ...
- MySQL数据库增删改查SQL语句(2018整理集合大全)
查看数据库 show databases; 使用数据库 use 数据库名; 创建数据库 CREATE DATABASE 数据库名; 删除数据库 DROP DATABASE 数据库名; 创建表 cre ...
随机推荐
- Struts 1.3(第一例) - Login
本想跳过直接学Struts 2的,想想,还是先学Struts 1,万一到时去那个公司,人家用的是1,那还是要学,以及了解下1与2的区别在哪里. 上例子,很简单的一个网上login例子,再思考下Stru ...
- 【linux】/etc/passwd文件
/etc/passwd文件内容格式 /etc/passwd是保存用户信息的文件. 格式:用户名: 密码 : uid : gid :用户描述:主目录:登陆shell 举个例子: root:x:0:0: ...
- Javascript跨域问题解决方案
---本方法来自网上,因最近项目需求,解决了三天未果,最终发现此文并测试可用. 一个 非常优雅绝妙的解决方案!话不多说,直接上解决方案原理图: 该图要解决的问题说明如下:在AAA.com域名下的ind ...
- LintCode "Continuous Subarray Sum"
A variation to a classical DP: LCS. class Solution { public: /** * @param A an integer array * @retu ...
- Makefile编译选项CC与CXX/CPPFLAGS、CFLAGS与CXXFLAGS/LDFLAGS
转自:http://www.firekyrin.com/archives/597.html 编译选项 让我们先看看 Makefile 规则中的编译命令通常是怎么写的. 大多数软件包遵守如下约定俗成的规 ...
- oracle中一个字符串包含另一个字符串中的所有字符
oracle中一个字符串包含另一个字符串中的所有字符 --解决监理报告中所勾选的标段信息,与该用户所管理的标段字符串不匹配的问题. select * from a where instr(a,b)&g ...
- Spring进阶之路(1)-Spring核心机制:依赖注入/控制反转
原文地址:http://blog.csdn.net/wangyang1354/article/details/50757098 我们经常会遇到这样一种情景,就是在我们开发项目的时候经常会在一个类中调用 ...
- eclipse 每次切换工作空间都要重新配置
首先,导出T1中的配置打开T1,选择file --> Export --> 在弹出框中选择General 下的preference --> next --> 在export p ...
- 两分钟彻底让你明白Android Activity生命周期(图文)!
大家好,今天给大家详解一下Android中Activity的生命周期,我在前面也曾经讲过这方面的内容,但是像网上大多数文章一样,基本都是翻译Android API,过于笼统,相信大家看了,会有一点点的 ...
- PLSQL_Oracle簇表和簇表管理Index clustered tables(案例)
2012-06-08 Created By BaoXinjian