mysql 循环批量插入
背景
前几天在MySql上做分页时,看到有博文说使用 limit 0,10 方式分页会有丢数据问题,有人又说不会,于是想自己测试一下。测试时没有数据,便安装了一个MySql,建了张表,在建了个while循环批量插入10W条测试数据的时候,执行时间之长无法忍受,便查资料找批量插入优化方法,这里做个笔记。
数据结构
寻思着分页时标准列分主键列、索引列、普通列3种场景,所以,测试表需要包含这3种场景,建表语法如下:
drop table if exists `test`.`t_model`; Create table `test`.`t_model`(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`uid` bigint COMMENT '业务主键',
`modelid` varchar(50) COMMENT '字符主键',
`modelname` varchar(50) COMMENT '名称',
`desc` varchar(50) COMMENT '描述',
primary key (`id`),
UNIQUE index `uid_unique` (`uid`),
key `modelid_index` (`modelid`) USING BTREE
) ENGINE=InnoDB charset=utf8 collate=utf8_bin;
为了方便操作,插入操作使用存储过程通过while循环插入有序数据,未验证其他操作方式或循环方式的性能。
执行过程
1、使用最简单的方式直接循环单条插入1W条,语法如下:
drop procedure if exists my_procedure; delimiter //
create procedure my_procedure()
begin
DECLARE n int DEFAULT 1;
WHILE n < 10001 DO
insert into t_model (uid,modelid,modelname,`desc`) value (n,CONCAT('id20170831',n),CONCAT('name',n),'desc');
set n = n + 1;
END WHILE;
end
//
delimiter ;
插入1W条数据,执行时间大概在6m7s,按照这个速度,要插入1000W级数据,估计要跑几天。
2、于是,构思加个事务提交,是否能加快点性能呢?测试每1000条就commit一下,语法如下:
delimiter //
create procedure u_head_and_low_pro()
begin
DECLARE n int DEFAULT 17541;
WHILE n < 10001 DO
insert into t_model (uid,modelid,modelname,`desc`) value (n,CONCAT('id20170831',n),CONCAT('name',n),'desc');
set n = n + 1;
if n % 1000 = 0
then
commit;
end if;
END WHILE;
end
//
delimiter ;
执行时间 6 min 16 sec,与不加commit执行差别不大,看来,这种方式做批量插入,性能是很低的。
3、使用存储过程生成批量插入语句执行批量插入插入1W条,语法如下:
drop procedure IF EXISTS u_head_and_low_pro; delimiter $$
create procedure u_head_and_low_pro()
begin
DECLARE n int DEFAULT 1;
set @exesql = 'insert into t_model (uid,modelid,modelname,`desc`) values ';
set @exedata = ''; WHILE n < 10001 DO
set @exedata = concat(@exedata,"(",n,",","'id20170831",n,"','","name",n,"','","desc'",")"); if n % 1000 = 0
then
set @exesql = concat(@exesql,@exedata,";"); prepare stmt from @exesql;
execute stmt;
DEALLOCATE prepare stmt;
commit; set @exesql = 'insert into t_model (uid,modelid,modelname,`desc`) values ';
set @exedata = "";
else
set @exedata = concat(@exedata,',');
end if; set n = n + 1;
END WHILE;
end;$$
delimiter ;
执行时间 3.308s。
总结
批量插入时,使用insert的values批量方式插入,执行速度大大提升。
mysql 循环批量插入的更多相关文章
- mysql循环批量插入测试数据
http://blog.51cto.com/tianxingzhe/1676097 DROP PROCEDURE test_insert ; DELIMITER $$ CREATE PROCEDURE ...
- Mysql 如何批量插入百万行测试数据
Mysql 如何批量插入百万行测试数据
- sql存储过程中循环批量插入
前几天有一个需求很头痛,部门是有上下级关系的,在给部门的经理赋予角色和权限的时候,通常我们都会认为假如经理A的部门是1,那么我给了他部门1 的管理权限,那么1的下级部门101,102,103 &quo ...
- C API 连接MySQL及批量插入
CMySQLMgr.h: #ifndef _CMYSQLMGR_H_ #define _CMYSQLMGR_H_ #include <iostream> #include "my ...
- Mybatis 针对ORACLE和MYSQL的批量插入与多参数批量删除
今天利用Mybatis的<for each>标签做oracle的批量插入数据时,发现和MySQL数据库有区别.在此记录下,以防之后再踩坑. 一.批量插入: 1.controller: /* ...
- php如何在mysql里批量插入数据
假如说我有这样一个表,我想往这个表里面插入大量数据 CREATE TABLE IF NOT EXISTS `user_info` ( `id` int(11) NOT NULL AUTO_INCREM ...
- mysql+ibatis 批量插入
述:相比oracle批量插入,mysql批量插入就简单的多了,mysql支持values后面跟多条数据,进行批量插入,并且主键可以自增,不像oracle会遇到序列问题. 1.建表 CREATE TAB ...
- Mysql优化批量插入数据
最近为了测试项目,需要在Mysql中插入百万级测试数据,于是用到了批量插入,自己写了个简单的Spring Cloud项目. 开始时执行效率很慢,大概100条/秒,批次的大小也试过1000,2000,5 ...
- 向mysql中批量插入数据的性能分析
MYSQL批量插入数据库实现语句性能分析 假定我们的表结构如下 代码如下 CREATE TABLE example (example_id INT NOT NULL,name VARCHAR( 5 ...
随机推荐
- Linux下异常信号
我们介绍一些标准信号的名称以及它们代表的事件.每一个信号名称是一个代表正整数的宏,但是你不要试图去推测宏代表的具体数值,而是直接使用名称.这是因为这个数值会随不同的系统或同样系统的不同版本而不同,但是 ...
- Maven新建webapp项目报错Could not resolve artifact org.apache.maven.archetypes:maven-archetype-webapp:pom:RELEASE
Windows-Preferences 在搜索框输入maven,点击下面的Archetypes--->Add Remote Catalog... 对应输入 http://repo1.maven. ...
- spring-boot-starter-data-redis与spring-boot-starter-redis两个包的区别
spring-boot-starter-data-redis: <?xml version="1.0" encoding="UTF-8"?> < ...
- js如何获取一个object的第一个数据
var obj = { "1":"123", "2":"456" } console.info( obj[Object. ...
- DRBD+Heratbeat+NFS高可用文件共享存储
一.概述 .通过ha-log日志可以看出主释放资源,备接管资源. 来自为知笔记(Wiz)
- JavaSE入门学习9:Java基础语法之数组
一数组的定义 数组能够理解为是一个巨大的"盒子",里面能够按顺序存放多个类型同样的数据.比方能够定义int型的数组 scores存储4名学生的成绩. watermark/2/tex ...
- 区分Integer.getInteger和Integer.valueOf、Integer.parseInt() 的使用方法
Integer类有两个看起来很类似的静态方法,一个是Integer.getInteger(String),另外一个是Integer.valueOf(String).如果只看方法名称的话,很容易将这两个 ...
- JQuery实现表格行的上移、下移、删除、增加
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%&g ...
- 【iOS系列】-iOS开发,GET,POST请求使用
[iOS系列]-iOS开发,GET,POST请求使用 步骤: 1:实例化URL(网络资源) 2:根据URL建立URLRequest(网络请求) 默认为GET请求: 对于POST请求,需要创建请求的数据 ...
- [IT学习]阿铭Linux 微信公众号 每日一题 解析
1.shell习题171020公布的昨日答案 习题171019 - 打印正方形 #!/bin/bash read -p "please input a number:" sum a ...