MySql || 快速创建100w条记录
平时每个开发者都会讨论数据量大时,sql的优化问题。但是并不是每个人都会有100w的数据量可以用来实战,那么今天我们就自己动手,模拟一个100w数据量的表。
- 创建原理
其实创建的方法有很多,有快的也有慢的。本博客中写的当然不是最快的那个,但确实是比较好操作和理解的。那么我先来说明一下它的原理:它是利用mysql中的在MEMORY引擎的特点,用于快速的插入100w的数据在内存中存放,然后再利用sql插入到目标的表当中。
- 操作步骤
- 创建表t_user,这是用于存放数据的表。
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c_user_id` varchar(36) NOT NULL DEFAULT '',
`c_name` varchar(22) NOT NULL DEFAULT '',
`c_province_id` int(11) NOT NULL,
`c_city_id` int(11) NOT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.创建内存表t_user_memory,这是用于快速插入数据的表。
CREATE TABLE `t_user_memory` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c_user_id` varchar(36) NOT NULL DEFAULT '',
`c_name` varchar(22) NOT NULL DEFAULT '',
`c_province_id` int(11) NOT NULL,
`c_city_id` int(11) NOT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MEMORY DEFAULT CHARSET=utf8mb4;
3.创建随机字符串函数randStr(),用于在给c_name赋值时更加随机。
delimiter $$
CREATE DEFINER=`root`@`%` FUNCTION `randStr`(n INT) RETURNS varchar(255) CHARSET utf8mb4
DETERMINISTIC
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() * 62), 1));
SET i=i+1;
END WHILE;
RETURN return_str;
END $$
这个函数的语法不用解释也会看得懂,但是还是有几个点需要注意的。
- delimiter关键字,这是一个声明结束符的关键字。简单的来说就是,防止和BEGIN和END之间的语句冲突,因为我们希望这里面的语句是连续执行的。
- CONCAT(str,str)链接两个字符串组成一个新的字符串。
- FLOOR(num)函数,向下取整。例如floor(1.23) = 1 、floor(-1.23) = -2。
4.创建随机时间函数randDataTime(),为了后期的时间更加随机。
delimiter $$
CREATE DEFINER = `root`@`%` FUNCTION `randDataTime` (sd DATETIME, ed DATETIME) RETURNS datetime DETERMINISTIC
BEGIN
DECLARE
sub INT DEFAULT 0 ;
DECLARE
ret DATETIME ;
SET sub = ABS(
UNIX_TIMESTAMP(ed) - UNIX_TIMESTAMP(sd)
) ;
SET ret = DATE_ADD(
sd,
INTERVAL FLOOR(1 + RAND() *(sub - 1)) SECOND
) ;
RETURN ret ;
END $$
里面的需要注意的是DATE_ADD(dateTime,INTERVAL num SECOND)函数,第一个参数是被添加的时间,第二个参数是一个组合,表明是添加的长度,如:(INTERVAL 1 YEAR)表示在原来的基础上添加一年的时间间隔。
5.创建插入数据存储过程add_t_user_memory (int)
delimiter $$
CREATE DEFINER=`root`@`%` PROCEDURE add_t_user_memory (IN n INT)
BEGIN
DECLARE
i INT DEFAULT 1 ;
WHILE i < n DO
INSERT INTO t_user_memory (
c_user_id,
c_name,
c_province_id,
c_city_id,
create_time
)
VALUES
(
uuid(),
randStr (20),
FLOOR(RAND() * 1000),
RAND() * 100,
NOW()
);
SET i = i + 1 ;
END
WHILE ;
END $$
- 执行过程中的问题
在完成上面的声明之后我们就可以用CALL add_t_user_memory (1000000)来创建100w的数据啦,这大概需要20分钟的时间。但是在调用的过程中却发现了一个问题如下图所示。

原来是't_user_memory' 已经满了。它是我在上面定义的用内存存放数据的表,在MYSQL中默认的大小是16MB。这个大小只能放4w多条数据,所以我们要想办法把它扩大。那么可以执行下面语句
SET GLOBAL max_heap_table_size = 1024 * 1024 * 1024 * 1; #查看当前的设置的大小
select @@max_heap_table_size;
注意:修改需要重新链接mysql才能更新修改。这个修改自己机器上玩玩就可以了,在生产环境这么改有什么后果我可不负责。
- 完善数据库
- 执行下面语句,大概需要10s就可以插入到t_user中。
INSERT INTO t_user SELECT * FROM t_user_memory;
2.打乱创建时间。
#更新年间隔
UPDATE t_user SET create_time=date_add(create_time, interval FLOOR(1 + (RAND() * 4)) year);
#更新秒间隔
UPDATE t_user SET create_time=randDataTime(NOW(),create_time);
- 完成
这样,我们的百万级数据库就创建完成啦!然后,我们可以将t_user_memory这个表清空,毕竟它是很占内存的,你数据有多少内存就占多少。下次再结合业务试试SQL优化怎么玩。

MySql || 快速创建100w条记录的更多相关文章
- MySQL快速生成100W条测试数据
https://blog.csdn.net/qq_16946803/article/details/81870174 1.生成思路利用mysql内存表插入速度快的特点,先利用函数和存储过程在内存表中生 ...
- php实现只保留mysql中最新1000条记录
这篇文章主要介绍了php实现只保留mysql中最新1000条记录的方法和相关示例及数据库结构,十分的全面,有需要的小伙伴可以参考下. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 1 ...
- mysql中插入多条记录-微软批处理
当向mysql中插入大量数据时,可以使用微软的批处理方式.这样可以防止内存溢出又提高了效率.我写了一个mysql中插入多条记录的例子.赋值代码可以直接使用. 1.首先需要添加两个dll MySql.D ...
- 快速生成100W条数据
快速生成100W条数据,生成的时候是顺序生成,取的时候是随机取用,生成100W条数据大概一分多钟,比网上其他代码速度要快很多 )) --truncate table tb --select top 1 ...
- 关于mysql查询最近一条记录
关于mysql查询最近一条记录 最近项目中遇到需要查询记录当前时间最近的一条记录的问题,开始感觉无从下手,后来逐步发现了三种解决方案. 下策——查询出结果后将时间排序后取第一条 select * fr ...
- user表中存在多条相同user不同host用户信息时MySQL该匹配哪条记录登录?
问题: 当用户名相同,但主机名不同的多条记录.用户由不同主机登录时,选择使用那条记录来验证,数据库版本为:5.6.25 如:IP为192.168.141.241 hostname为vhost02主机上 ...
- [mysql] 查询前几条记录
From: http://www.cnblogs.com/xuxm2007/archive/2010/11/16/1878211.html SELECT * FROM table LI ...
- mysql 随机选取一条记录
要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RAND() LIMIT 1. 1 2 3 4 5 6 7 8 9 1 ...
- MySQL 快速添加百万条数据
需要向数据库添加100W条测试数据,直接在普通表中添加速度太慢,可以使用内存表添加,然后将内存表数据复制到普通表 创建表 # 内存表 DROP TABLE IF EXISTS `test_memory ...
随机推荐
- BZOJ5243 : [Lydsy2017省队十连测]绝版题
要找的就是这棵树的带权重心,以带权重心为根时每棵子树的权值和不超过总权值和的一半. 因此按$\frac{v[i]}{\sum v[i]}$的概率随机选取一个点$x$,则重心有$\frac{1}{2}$ ...
- flask回顾
pip install flask from flask import Flask app = Flask(__name__) # 命令行启动,用manager,访问会变的非常慢 pip instal ...
- netcat 传输T级别大文件
接收端 nc -d -l 5002 |tar xf - nohup sh receive.sh & 发送端 tar cf - . | nc 1.1.1.1 5002 nohup ...
- Spring Cloud(十四):Ribbon实现客户端负载均衡及其实现原理介绍
年后到现在一直很忙,都没什么时间记录东西了,其实之前工作中积累了很多知识点,一直都堆在备忘录里,只是因为近几个月经历了一些事情,没有太多的经历来写了,但是一些重要的东西,我还是希望能坚持记录下来.正好 ...
- pytorch_01_基础_一维线性回归
pytorch基础 pytorch官方文档:https://pytorch.org/docs/master/nn.html#linear-layers import torchfrom torch i ...
- IntelliJ IDEA 超实用使用技巧分享
https://blog.csdn.net/weixin_38405253/article/details/102583954 知识点概览: 高效率配置 日常使用 必备快捷键(★★) 查找 跳转切换 ...
- oracle查看执行计划入门
基于Oracle的应用系统很多的性能问题都是由应用系统的SQL性能低劣引起的,因此SQL的性能优化非常重要.要分析与优化SQL的性能,一般是通过查看该SQL的执行计划,然后通过执行计划有针对性地对SQ ...
- 汇编语言01 - 打印 "Hello World!"
Hello World! 源代码 data segment msg db "Hello World!$";定义名称为msg的字符串,最后加上$,表示字符串结束 data ends ...
- http内网转发
package main import ( "io" "log" "net/http" "strings" ) func ...
- Linux学习笔记之AIX系统上压缩与解压文件
0x00 概述 AIX机器真难用,一时半会还真适应不了. 0x01 压缩tar 命令格式: # tar -cvf (或xvf)+文件名+设备 C:是本地到其他设备 x:是其他设备到本地 r:是追加 ...