背景

前几天在MySql上做分页时,看到有博文说使用 limit 0,10 方式分页会有丢数据问题,有人又说不会,于是想自己测试一下。测试时没有数据,便安装了一个MySql,建了张表,在建了个while循环批量插入10W条测试数据的时候,执行时间之长无法忍受,便查资料找批量插入优化方法,这里做个笔记。

数据结构

寻思着分页时标准列分主键列、索引列、普通列3种场景,所以,测试表需要包含这3种场景,建表语法如下:

  1. drop table if exists `test`.`t_model`;
  2.  
  3. Create table `test`.`t_model`(
  4. `id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  5. `uid` bigint COMMENT '业务主键',
  6. `modelid` varchar(50) COMMENT '字符主键',
  7. `modelname` varchar(50) COMMENT '名称',
  8. `desc` varchar(50) COMMENT '描述',
  9. primary key (`id`),
  10. UNIQUE index `uid_unique` (`uid`),
  11. key `modelid_index` (`modelid`) USING BTREE
  12. ) ENGINE=InnoDB charset=utf8 collate=utf8_bin;

为了方便操作,插入操作使用存储过程通过while循环插入有序数据,未验证其他操作方式或循环方式的性能。

执行过程

1、使用最简单的方式直接循环单条插入1W条,语法如下:

  1. drop procedure if exists my_procedure;
  2.  
  3. delimiter //
  4. create procedure my_procedure()
  5. begin
  6. DECLARE n int DEFAULT 1;
  7. WHILE n < 10001 DO
  8. insert into t_model (uid,modelid,modelname,`desc`) value (n,CONCAT('id20170831',n),CONCAT('name',n),'desc');
  9. set n = n + 1;
  10. END WHILE;
  11. end
  12. //
  13.                
  14. delimiter ;

插入1W条数据,执行时间大概在6m7s,按照这个速度,要插入1000W级数据,估计要跑几天。
2、于是,构思加个事务提交,是否能加快点性能呢?测试每1000条就commit一下,语法如下:

  1. delimiter //
  2. create procedure u_head_and_low_pro()
  3. begin
  4. DECLARE n int DEFAULT 17541;
  5. WHILE n < 10001 DO
  6. insert into t_model (uid,modelid,modelname,`desc`) value (n,CONCAT('id20170831',n),CONCAT('name',n),'desc');
  7. set n = n + 1;
  8. if n % 1000 = 0
  9. then
  10. commit;
  11. end if;
  12. END WHILE;
  13. end
  14. //
  15. delimiter ;

执行时间 6 min 16 sec,与不加commit执行差别不大,看来,这种方式做批量插入,性能是很低的。

3、使用存储过程生成批量插入语句执行批量插入插入1W条,语法如下:

  1. drop procedure IF EXISTS u_head_and_low_pro;
  2.  
  3. delimiter $$
  4. create procedure u_head_and_low_pro()
  5. begin
  6. DECLARE n int DEFAULT 1;
  7. set @exesql = 'insert into t_model (uid,modelid,modelname,`desc`) values ';
  8. set @exedata = '';
  9.  
  10. WHILE n < 10001 DO
  11. set @exedata = concat(@exedata,"(",n,",","'id20170831",n,"','","name",n,"','","desc'",")");
  12.  
  13. if n % 1000 = 0
  14. then
  15. set @exesql = concat(@exesql,@exedata,";");
  16.  
  17. prepare stmt from @exesql;
  18. execute stmt;
  19. DEALLOCATE prepare stmt;
  20. commit;
  21.  
  22. set @exesql = 'insert into t_model (uid,modelid,modelname,`desc`) values ';
  23. set @exedata = "";
  24. else
  25. set @exedata = concat(@exedata,',');
  26. end if;
  27.  
  28. set n = n + 1;
  29. END WHILE;
  30. end;$$
  31. delimiter ;

执行时间 3.308s。

总结

批量插入时,使用insert的values批量方式插入,执行速度大大提升。

mysql 循环批量插入的更多相关文章

  1. mysql循环批量插入测试数据

    http://blog.51cto.com/tianxingzhe/1676097 DROP PROCEDURE test_insert ; DELIMITER $$ CREATE PROCEDURE ...

  2. Mysql 如何批量插入百万行测试数据

    Mysql 如何批量插入百万行测试数据

  3. sql存储过程中循环批量插入

    前几天有一个需求很头痛,部门是有上下级关系的,在给部门的经理赋予角色和权限的时候,通常我们都会认为假如经理A的部门是1,那么我给了他部门1 的管理权限,那么1的下级部门101,102,103 &quo ...

  4. C API 连接MySQL及批量插入

    CMySQLMgr.h: #ifndef _CMYSQLMGR_H_ #define _CMYSQLMGR_H_ #include <iostream> #include "my ...

  5. Mybatis 针对ORACLE和MYSQL的批量插入与多参数批量删除

    今天利用Mybatis的<for each>标签做oracle的批量插入数据时,发现和MySQL数据库有区别.在此记录下,以防之后再踩坑. 一.批量插入: 1.controller: /* ...

  6. php如何在mysql里批量插入数据

    假如说我有这样一个表,我想往这个表里面插入大量数据 CREATE TABLE IF NOT EXISTS `user_info` ( `id` int(11) NOT NULL AUTO_INCREM ...

  7. mysql+ibatis 批量插入

    述:相比oracle批量插入,mysql批量插入就简单的多了,mysql支持values后面跟多条数据,进行批量插入,并且主键可以自增,不像oracle会遇到序列问题. 1.建表 CREATE TAB ...

  8. Mysql优化批量插入数据

    最近为了测试项目,需要在Mysql中插入百万级测试数据,于是用到了批量插入,自己写了个简单的Spring Cloud项目. 开始时执行效率很慢,大概100条/秒,批次的大小也试过1000,2000,5 ...

  9. 向mysql中批量插入数据的性能分析

    MYSQL批量插入数据库实现语句性能分析 假定我们的表结构如下 代码如下   CREATE TABLE example (example_id INT NOT NULL,name VARCHAR( 5 ...

随机推荐

  1. spring-security 理解 笔记 介绍以及使用(持续更新)

    本人经过2周的学习,成功搭建了认证服务器,资源服务器和客户端 .下面是本人对 oauth2的理解,以及spring-security的使用,如果理解错误的地方,还望指正. 现在代码有点凌乱,过段时间会 ...

  2. Java子类重写父类方法注意问题收集(转)

    子类不能重写父类的静态方法,私有方法.即使你看到子类中存在貌似是重写的父类的静态方法或者私有方法,编译是没有问题的,但那其实是你重新又定义的方法,不是重写.具体有关重写父类方法的规则如下: 重写规则之 ...

  3. apache下配置认证用户

    有时候我们须要给我apacheserver下制定的文件夹加上用户认证,方便一些而用户进行文件的浏览.配置例如以下: 1 设置用户 1 htpasswd -c file_path user_name 回 ...

  4. vue 手风琴组件

    1.创建组件 SqueezeBox.vue <!-- 手风琴(三级折叠列表) 组件 --> <template> <div class="header" ...

  5. 【转】SQL中的取整函数FLOOR、ROUND、CEIL、TRUNC、SIGN

    --------------------------------------------------------------------------1 trunc(value,precision)按精 ...

  6. UIButton的图片和文字相对位置调整

    通常.假设直接设置UIButton的图片和文字,默认的两者相对位置可能不是我们想要的,那么须要进行调整. 须要用到的函数例如以下: UIEdgeInsetsMake(CGFloat top, CGFl ...

  7. pat(A)1041. Be Unique(哈希)

    1.链接:点击打开链接 2.代码: #include<cstdio> #include<iostream> #include<cstring> using name ...

  8. mingw在Dos下升级gnu编译器版本

    在dos窗口下输入: mingw-get update mingw-get upgrade gfortran gcc g++ 强烈建议卸载后再安装新版本

  9. 基于开源项目的在线网络视频直播项目---一个很好的电视直播开源项目Sopcast

    http://blog.csdn.net/roy_xu/article/details/2216559 http://115.com/?ct=rar&pickcode=ew52634xr2cr ...

  10. 2016/04/26 权限 数据库mydb2 五个表 分别是 1,用户 2,角色 3,权限 4,用户对应的角色 5,角色对应的权限

    权限:   1,后台分配角色     角色对应权限    2,各用户通过登录页面登录    查看到各自的权限 五个页面   加引入一个jquery-1.11.2.min.js 1,guanli.php ...