要学习MySQL的优化自然是少不了测试用的学习环境,也就是说我们应该能够 有一个比较贴近实际生产环境的MySQL环境,然后,根据这个环境才可以学习MySQL的优化。
我们通常学习MySQL的优化,其内容主要指的是SQL语句的优化,因为开发给出的良好的SQL语句会保证MySQL这个软件稳定高效的运行啦,其次是表结构的优化,再次是服务器和MySQL服务的优化。
那么,一般的MySQL测试环境应该有哪些内容呢?
第一,一个MySQL运行的实例,虚拟机或者物理机都可以啦,不过虚拟机更加方便喽。
第二,有多张的表,可以做联合查询,并且主要的表内数据量能够达到百万级别。(为什么要这么大的数据量呢?因为慢查询的优化是SQL语句优化的一个重要部分啦)
第三,硬件条件不是特别差,至少能跑动数据库是一个前提条件吧~~~~~~~
OK,有一个不管放哪的MySQL测试数据库,只要能连接到就OK了,这个相信对各位朋友来说 so easy。下面,是要有一个百万级别的一组大表了。
A:
首先,建立一个空的数据库,然后在这个数据库内建立三张空表,这几个表就是经常做联合查询的emp表啦,SQL语句如下:
cat createtables.sql
create database if not exists temps;
use temps;
#创建表DEPT
CREATE TABLE if not exists 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 if not exists 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 if not exists 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);
B:
为了存储过程能够正常执行,我们需要把命令执行结束符修改,进入MySQL命令行,执行以下命令:
delimiter $$
C:
创建一个函数,此函数接收一个整数,然后将该整数转换成随机的字符串
#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 $$
D:
定义一个函数,产生随机部门编号:
create function rand_num( )
returns int(5)
begin
declare i int default 0;
set i = floor(10+rand()*500);
return i;
end $$
E:
创建一个存储过程,代码如下:
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 $$
F:
调用刚刚写好的函数, 4000000条记录,从100001号开始
call insert_emp(100001,4000000)$$
附记:
这三个表生成的时候没有主键,外键这些索引,主要是为了后面索引优化的时候学习使用才没有添加。