MySQL如何按表创建千万级的测试数据,进行数据库压力测试和练习

前言

笔者采用Intellij IDEA内置的数据库模块进行操作,也推荐大家使用专业点的IDE来操作数据库,通过命令行是很痛苦的。但是您要用命令行来操作以下内容,也是可以的,我会尽量照顾到您的使用习惯,但是不保证代码都能执行无误

在学习完数据库及SQL的知识之后,想必各位同学都对数据库的性能优化有很深的兴趣,但是性能优化都是基于TB级的数据进行的。

什么是TB级的数据

今天我就带着大家来利用MySQL循环和存储过程做一个对特定表的创建千万行数据的实例


假设我们目前有这样一张表:

users表

这张表有7个Columns,对应7个常见的简单的用户属性

为了照顾性少数者人群,把gender设为可变字符型较合适

随机生成数据

大家可能知道MySQL里面自带一个随机数生成的函数RAND()
它能生成0-1的浮点数

RAND函数生成随机数的语法

生成的结果

这里是常用函数大全 可当手册查

随机生成给定数目的字符串

随机生成给定数目的字符串

这里的循环采用WHILE循环,循环里面采用字符串拼接函数CONCAT
可复制的代码见下:

CREATE DEFINER =`您的数据库名`@`您的主机地址` FUNCTION `rand_string`(n INT)
  RETURNS VARCHAR(255)
  CHARSET utf8
  BEGIN
    DECLARE chars_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(chars_str, FLOOR(1 + RAND() * 80), 1));
      SET i = i + 1;
    END WHILE;
    RETURN return_str;
  END;
生成的字符串实例

用户名和密码都可以通过以上介绍的方式添加

邮箱的添加方式
可直接在insertvalue对应字段写上concat(rand_string(5), '@qq.com')既可


随机生成DATEDATETIME类型

随机生成DATE类型实例

关于LPAD函数,具体做为月份和日期的补零作用!生效如下介绍

Returns the string str:str, left-padded with the string padstr to a length of len characters. If str is longer than len:N, the return value is shortened to len characters.
mysql> SELECT LPAD('hi',4,'??');
-> '??hi'
mysql> SELECT LPAD('hi',1,'??');
-> 'h'

可复制代码见下:

CREATE DEFINER =`您的数据库名`@`您的主机地址` FUNCTION `randDate`()
  RETURNS VARCHAR(255)
  CHARSET utf8
  BEGIN
    DECLARE aDate CHAR(10) DEFAULT '';
    SET aDate = CONCAT(1949 + FLOOR((RAND() * 68)), '-', LPAD(FLOOR(1 + (RAND() * 12)), 2, 0), '-',
                       LPAD(FLOOR(3 + (RAND() * 8)), 2, 0));
    RETURN aDate;
  END;
运行实例
随机生成DATE类型

关于DATETIME类型
在刚刚写好的randDate上进行改造,加上一下这句话就好了

CONCAT(LPAD(FLOOR(0 + (RAND() * 23)),2,0),':',LPAD(FLOOR(0 + (RAND() * 60)),2,0),':',LPAD(FLOOR(0 + (RAND() * 60)),2,0))
随机生成DATETIME类型的代码

可复制版本如下:

CREATE DEFINER =`您的数据库名`@`您的主机地址` FUNCTION `randDateTime`()
  RETURNS VARCHAR(255)
  CHARSET utf8
  BEGIN
    DECLARE aDateTime CHAR(19) DEFAULT '';
    SET aDateTime = CONCAT(CONCAT(1949 + FLOOR((RAND() * 68)), '-', LPAD(FLOOR(1 + (RAND() * 12)), 2, 0), '-',
                                  LPAD(FLOOR(3 + (RAND() * 8)), 2, 0)),
                           ' ',
                           CONCAT(LPAD(FLOOR(0 + (RAND() * 23)), 2, 0), ':', LPAD(FLOOR(0 + (RAND() * 60)), 2, 0), ':',
                                  LPAD(FLOOR(0 + (RAND() * 60)), 2, 0))
    );
    RETURN aDateTime;
  END;

执行效果如下:

执行过程
执行效果

如果是时间戳类型,TIMESTAMP,那就是存一个特定范围的随机数我不再多做演示


gender性别的存法

用我们最上面写的那个随机字符串的方法进行改造,把chars_str的default内容改成“男,女等等”就好了,为避免文章冗长,不再做演示


将数据循环插入

我们的整个最主要的方法就是基于MySQL的存储过程

我向来不爱先讲定义,我给大家以实例导入

定义将数据循环的存储过程

上图是一个10W次的插入实例,亲测耗时非常久,如果需要在30s内结束的,建议改成1w条,也够测试了

这里需要注意的是DELIMITER//和DELIMITER;两句, DELIMITER是分割符的意思,因为MySQL默认以";"为分隔 符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错,所以要事先用DELIMITER关键字申明当 前段分隔符,这样MySQL才会将";"当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原。

也就是说如果你在命令行里面执行创建存储过程的语句时,是会出错的,因为sql遇到分号就结束了

我这里采用Intellij IDEA内置的DataGrip Console里面执行的,不用定义DELIMITER,在END后面加上;就好了,也推荐大家使用IDE来操作数据库,通过命令行是很痛苦的

可复制代码如下:

DELIMITER //
CREATE PROCEDURE insertManyUser()
  BEGIN
    DECLARE num INT;
    SET num = 1;
    WHILE num < 1000000 DO
      INSERT INTO users (username, email, password, birthday, gender, avatar)
      VALUES (rand_string(15), concat(rand_string(5), '@qq.com'), rand_string(32),
              randDate(), 'male', NULL);
      SET num = num + 1;
    END WHILE;
  END;
//

定义好存储过程insertManyUser之后还没有完,我们需要CALL它才可以

CALL insertManyUser;

然后等着慢慢的创建过程,测试用数据就到手了

这里是完全版的存储过程详解 可当手册查


最终生成的测试用数据

测试数据的处理

1.清空数据库

  • 不可回滚式:
DELETE FROM users;
  • 可回滚式:
TRUNCATE TABLE users;

有外键存在的话,TRUNCATE不可用

2.MySQL修改存储过程

ALTER PROCEDURE
更改用CREATE PROCEDURE 建立的预先指定的存储过程,其不会影响相关存储过程或存储功能。

  1. MySQL存储过程的删除

删除一个存储过程比较简单,和删除表一样:

DROP PROCEDURE

从MySQL的表格中删除一个或多个存储过程。

4.如果您需要改变FUNCTION返回值类型
可查看这篇文章


您在生成测试数据的时候遇到什么问题,都可以在下面留言和我交流,共同成长。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容