一
1.建表
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`user_id` bigint(100) NOT NULL AUTO_INCREMENT,
`username` varchar(100) DEFAULT NULL COMMENT '用户名',
`password` varchar(100) DEFAULT NULL COMMENT '密码',
`salt` varchar(100) DEFAULT NULL COMMENT '盐',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`mobile` varchar(100) DEFAULT NULL COMMENT '手机号',
`status` varchar(100) DEFAULT NULL COMMENT '状态 0:禁用 1:正常',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=112758 DEFAULT CHARSET=utf8 COMMENT='系统用户';
SET FOREIGN_KEY_CHECKS=1;
2.执行show variables like ‘log_bin_trust_function_creators’;设置为ON。开启状态。
set global log_bin_trust_function_creators=1;
在这里插入图片描述
3.创建函数
# 随机字符串
DELIMITER $$
CREATE FUNCTION random_string(n INT) RETURNS VARCHAR(255)
BEGIN
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 $$
CREATE FUNCTION random_num( )
RETURNS INT(5)
BEGIN
DECLARE i INT DEFAULT 0;
SET i = FLOOR(100+RAND()*10);
RETURN i;
END $$
#执行存储过程,往sys_user表添加随机数据
DELIMITER $$
CREATE PROCEDURE insert_sys_user(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 sys_user (user_id,username,password,salt,email,mobile,status) VALUES (START+i,random_string(10),random_string(6),random_string(10),random_string(20),random_string(16),random_string(12));
UNTIL i = max_num
END REPEAT;
COMMIT;
END $$
#执行存储过程,往sys_user表添加50万条数据
DELIMITER ;
CALL insert_sys_user(100001,500000);
删除:
使用DROP语句,语法如下:
DROP {PROCEDURE | FUNCTION} [IF EXISTS] proc_name
DROP FUNCTION proc_countByName;
DROP FUNCTION IF EXISTS proc_countByName;
使用SHOW STATUS查看状态
SHOW STATUS查看存储过程和函数的状态,语法如下:
SHOW {PROCEDURE | FUNCTION} STATUS [LIKE 'parttern']
这个语句是MySQL的扩展,它返回子程序的特征,如数据库、名字、类型、创建者及创建和修改日期。如果没有指定样式,根据使用的语句,所有存储程序或存储函数的信息都被列出。PROCEDURE和FUNCTION分别表示查看存储过程和函数;LIKE语句表示匹配存储过程或函数名称。
示例:
SHOW PROCEDURE STATUS LIKE 'proc_%';
二、快速生成大量测试数据(100万、1000万、1亿)
这种做法生成的测试数据相对比较符合实际,注册时间和最后登录时间都既有一定的时间顺序,又有在时间区间内有随机生成,代码都有注释,这里就不多说了,代码如下:
#建测试表
drop table if exists t;
CREATE TABLE t (
id int NOT NULL AUTO_INCREMENT PRIMARY KEY comment '自增主键',
dept tinyint not null comment '部门id',
age tinyint not null comment '年龄',
name varchar(30) comment '用户名称',
create_time datetime not null comment '注册时间',
last_login_time datetime comment '最后登录时间'
) comment '测试表';
#手工插入第一条测试数据,后面数据会根据这条数据作为基础生成
insert into t values(1,1, 25, 'user_1', '2018-01-01 00:00:00', '2018-03-01 12:00:00');
#初始化序列变量
set @i=1;
#==================此处拷贝反复执行,直接符合预想的数据量===================
#执行20次即2的20次方=1048576 条记录
#执行23次即2的23次方=8388608 条记录
#执行24次即2的24次方=16777216 条记录
#......
insert into t(dept, age, name, create_time, last_login_time)
select left(rand()*10,1) as dept, #随机生成1~10的整数
FLOOR(20+RAND() *(50 - 20 + 1)) as age, #随机生成20~50的整数
concat('user_',@i:=@i+1), #按序列生成不同的name
date_add(create_time,interval +@i*cast(rand()*100 as signed) SECOND), #生成有时间大顺序随机注册时间
date_add(date_add(create_time,interval +@i*cast(rand()*100 as signed) SECOND), interval + cast(rand()*1000000 as signed) SECOND) #生成有时间大顺序的随机的最后登录时间
from t;
select count(1) from t;
#==================此处结束反复执行=====================
#创建索引(视情况执行)
create index idx_dept on t(dept);
create index idx_create_time on t(create_time);
create index idx_last_login_time on t(last_login_time);
上面也可以改写成存储过程,但这也不是每天执行就懒得改了,就这样吧,怎么简单怎么做。
三、
新建一个表格名为(dept)
CREATE TABLE dept( /*部门表*/
deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
dname VARCHAR(20) NOT NULL DEFAULT "",
loc VARCHAR(13) NOT NULL DEFAULT ""
) ;
在建一个表名为emp表
#创建表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 /*部门编号*/
) ;
在创建一个工资级别表salgrade
#工资级别表
CREATE TABLE salgrade
(
grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
losal DECIMAL(17,2) NOT NULL,
hisal DECIMAL(17,2) NOT NULL
);
然后像工资级别表插入数据
#测试数据
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 $$命令结束标志。
二.创建一个函数
#创建一个函数,名字 rand_string,可以随机返回我指定的个数字符串
create function rand_string(n INT)
returns varchar(255) #该函数会返回一个字符串
begin
#定义了一个变量 chars_str, 类型 varchar(100)
#默认给 chars_str 初始值 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'
declare chars_str varchar(100) default
'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
declare return_str varchar(255) default '';
declare i int default 0;
while i < n
do
# concat 函数 : 连接函数mysql函数
set return_str =concat(return_str,substring(chars_str,floor(1+rand()*52),1));
set i = i + 1;
end while;
return return_str;
end $$
//简单解释一下这段代码的意思:
自定义函数目的:返回一个指定长度的随机字符串。
chars_str:初始化长度为52位字符。
Mysql定义变量和我们平时使用的C或者Java不一样,因为人家毕竟也算一门语言,所以风格自然也有所变化。
对于一个变量的使用需要先用declarer声明一个变量
declare chars_str varchar(100) default
1
然后就是一个while函数循环,通过concat()函数的拼接,返回一个指定长度n的串串。
接着继续创建一个自定义函数:
#这里我们又自定了一个函数,返回一个随机的部门号
create function rand_num( )
returns int(5)
begin
declare i int default 0;
set i = floor(10+rand()*500);
return i;
end $$
#创建一个存储过程, 可以添加雇员
create procedure insert_emp(in start int(10),in max_num int(10))
begin
declare i int default 0;
#set autocommit =0 把autocommit设置成0
#autocommit = 0 含义: 不要自动提交
set autocommit = 0; #默认不提交sql语句
repeat
set i = i + 1;
#通过前面写的函数随机产生字符串和部门编号,然后加入到emp表
insert into emp values ((start+i) ,rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand_num());
until i = max_num
end repeat;
#commit整体提交所有sql语句,提高效率
commit;
end $$
执行:
call insert_emp(100001,8000000)$$
大约需要6-10分钟能执行完
四、快速生成批量测试数据
-- 创建一个临时内存表 set global log_bin_trust_function_creators=1; DROP TABLE IF EXISTS `vote_recordss_memory`; CREATE TABLE `vote_recordss_memory` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `user_id` varchar(20) NOT NULL DEFAULT '', `vote_num` int(10) unsigned NOT NULL DEFAULT '0', `group_id` int(10) unsigned NOT NULL DEFAULT '0', `status` tinyint(2) unsigned NOT NULL DEFAULT '1', `create_time` datetime NOT NULL DEFAULT '1971-01-01 01:01:01', PRIMARY KEY (`id`), KEY `index_user_id` (`user_id`) USING HASH ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- 创建一个普通表,用作模拟大数据的测试用例 DROP TABLE IF EXISTS `vote_records`; CREATE TABLE `vote_records` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `user_id` varchar(20) NOT NULL DEFAULT '' COMMENT '用户Id', `vote_num` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '投票数', `group_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '用户组id 0-未激活用户 1-普通用户 2-vip用户 3-管理员用户', `status` tinyint(2) unsigned NOT NULL DEFAULT '1' COMMENT '状态 1-正常 2-已删除', `create_time` datetime NOT NULL DEFAULT '1971-01-01 01:01:01' COMMENT '创建时间', PRIMARY KEY (`id`), KEY `index_user_id` (`user_id`) USING HASH COMMENT '用户ID哈希索引' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='投票记录表';
-- 为了数据的随机性和真实性,我们需要创建一个可生成长度为n的随机字符串的函数。 -- 创建生成长度为n的随机字符串的函数 DELIMITER // -- 修改MySQL delimiter:'//' DROP FUNCTION IF EXISTS `rand_strings` // SET NAMES utf8 // CREATE FUNCTION `rand_strings` (n INT) RETURNS VARCHAR(255) CHARSET 'utf8' BEGIN DECLARE char_str varchar(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; DECLARE return_str varchar(255) DEFAULT ''; DECLARE i INT DEFAULT 0; WHILE i < n DO SET return_str = concat(return_str, substring(char_str, FLOOR(1 + RAND()*62), 1)); SET i = i+1; END WHILE; RETURN return_str; END //
-- 为了操作方便,我们再创建一个插入数据的存储过程 -- 创建插入数据的存储过程 DROP PROCEDURE IF EXISTS `insert_vote_recordss_memory` // CREATE PROCEDURE `insert_vote_recordss_memory`(IN n INT) BEGIN DECLARE i INT DEFAULT 1; DECLARE vote_num INT DEFAULT 0; DECLARE group_id INT DEFAULT 0; DECLARE status TINYINT DEFAULT 1; WHILE i < n DO SET vote_num = FLOOR(1 + RAND() * 10000); SET group_id = FLOOR(0 + RAND()*3); SET status = FLOOR(1 + RAND()*2); INSERT INTO `vote_recordss_memory` VALUES (NULL, rand_strings(20), vote_num, group_id, status, NOW()); SET i = i + 1; END WHILE; END // DELIMITER ; -- 改回默认的 MySQL delimiter:';'
-- 开始执行存储过程,等待生成数据(100W条) -- 调用存储过程 生成100W条数据 CALL insert_vote_recordss_memory(10000000);
-- 查询内存表已生成记录(为了下步测试,目前仅生成了x条) SELECT count(*) FROM `vote_recordss_memory`;
-- 把数据从内存表插入到普通表中(100w条数据ys就插入完了) INSERT INTO vote_records SELECT * FROM `vote_recordss_memory`;
-- 查询普通表已的生成记录 SELECT count(*) FROM `vote_records`;
# 实时监控mysql的工具 https://blog.csdn.net/u013820054/article/details/54022456
---------+-------mysql-status-------+-----threads-----+-----slow-----+---bytes---+---------locks---------- time | QPS TPS ins upd del| run con cre cac| sql tmp Dtmp| recv send| lockI lockW openT openF ---------+--------------------------+-----------------+--------------+-----------+------------------------ 23:15:03 | 0 3738 3738 0 0| 3 3 0 0| 0 1 0| 0K 8K| 1 0 121 27 23:15:04 | 0 3781 3781 0 0| 3 3 0 0| 0 1 0| 0K 8K| 1 0 121 27 23:15:05 | 0 3733 3733 0 0| 3 3 0 0| 0 1 0| 0K 8K| 1 0 121 27 23:15:06 | 0 3737 3737 0 0| 3 3 0 0| 0 1 0| 0K 8K| 1 0 121 27 23:15:07 | 0 3576 3576 0 0| 3 3 0 0| 0 1 0| 0K 8K| 1 0 121 27 23:15:08 | 0 3589 3589 0 0| 2 3 1 1| 1 1 0| 0K 8K| 1 0 121 27 23:15:09 | 0 3548 3548 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:10 | 0 3791 3791 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:11 | 0 3861 3861 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:12 | 0 3892 3892 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:13 | 0 3857 3857 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:14 | 0 3900 3900 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:15 | 0 3701 3701 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:16 | 0 3856 3856 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:17 | 0 3166 3166 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:18 | 0 3865 3865 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:19 | 1 3853 3853 0 0| 3 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:20 | 0 2864 2864 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:21 | 0 2927 2927 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27 23:15:22 | 0 3820 3820 0 0| 2 3 0 1| 0 1 0| 0K 8K| 1 0 121 27