最近尝试插入1百万条数据进db,以mysql为例。

1. 顺序insert

先写了个无脑的for循环作为base-line,插1万条耗时1m53s,根本不敢插1百万。

foreach(var student in students){
var sql = string.Format("insert into student ... ");
cmd.CommandText = sql;
cmd.ExecuteNonQuery();
}

2. batch insert

上面这种方式有2个问题:

  1. 在DB端,每次执行都会以1个单独的事务执行;
  2. 在网络上,传输的次数过多、每次传输的效率较差。

相应的解决方法是:

  1. 在执行前后套BeginTransaction/Commit,保证所有的insert都是在一个大事务里; // 光是这样,1万条只要不到2s,1百万条只要75s

  2. 每1万条数据,拼接成1个大sql,只要不超过 max_allowed_packet=1M 的默认限制即可。具体多少行拼成1条,视字段多少而定,拼成的sql如下。 // 这样的效果也很显著,1百万条只要13s

     insert into table (fields...) values (1...), (2...), ... , (10000...);
  3. 可以修改mysql的默认设置,在my.ini里添加如下配置。但试下来效果并不明显,改成10M、每次拼接10万条数据,总时间仍为13s,可以想见这时瓶颈已经不是传输时间了,而是对表的操作。

     [mysqld]
    max_allowed_packet=10M // 1M default

3. MultiThread insert

试了下在方法2(batch insert)的基础上,采用4个线程同时insert,1百万条数据耗时16s,反而慢了。估计时间都耗在创建connection、单表加锁上了。在这个场景下,MultiThread对解决问题无益。

4. ibdata1无限增长的问题

每个Student对象大约是50字节,每insert1百万大约是50M。多insert几次后执行删除操作,发现ibdata1文件反而接近翻倍的增长。解决方法如下:

  • 关闭mysqld服务
  • 删除ibdata1、ib_logfile0/1、对应的database文件夹
  • my.ini的[mysqld]里添加 innodb_file_per_table=1 ,这样就会给每个表创建一个单独的ibd文件

最后是Demo的源码,如果你有更快的方法,不妨留言~

batch insert 1 million datas into mysql的更多相关文章

  1. 使用batch insert解决MySQL的insert吞吐量问题

    最近使用了一个非常简单易用的方法解决了业务上的一个insert吞吐量的问题,在此总结一下. 首先我们明确一下,insert吞吐量其实并不是指的IPS(insert per second),而是指的RP ...

  2. oracle中的insert all into,在mysql中的写法

    oracle中的insert all into表示插入多条数据,mysql中可以采用: INSERT INTO表名(字段1,字段2..) values <foreach collection=& ...

  3. 【Insert】使用java对mysql数据库进行插入操作

    //插入100条数据package database; import java.sql.Connection; import java.sql.DriverManager; import java.s ...

  4. 简单的sqlserver批量插入数据easy batch insert data use loop function in sqlserver

    --example 1: DECLARE @pid INT,@name NVARCHAR(50),@level INT,@i INT,@column2 INT SET @pid=0 SET @name ...

  5. 【java】[sql]使用Java程序向MySql数据库插入一千万条记录,各种方式的比较,最后发现insert批量插入方式对效率提升最明显

    我的数据库环境是mysql Ver 14.14 Distrib 5.6.45, for Linux (x86_64) using EditLine wrapper 这个数据库是安装在T440p的虚拟机 ...

  6. MySQL中的insert ignore into, replace into等的一些用法总结

    在MySQL中进行条件插入数据时,可能会用到以下语句,现小结一下.我们先建一个简单的表来作为测试: CREATE TABLE `books` ( `id` INT(11) NOT NULL AUTO_ ...

  7. MySQL中的insert ignore into, replace into等的一些用法小结(转)

    MySQL中的insert ignore into, replace into等的一些用法总结(转) 在MySQL中进行条件插入数据时,可能会用到以下语句,现小结一下.我们先建一个简单的表来作为测试: ...

  8. mysql插入记录INSERT与多表更新

    1.第一种:INSERT [INTO] tbl_name[ (col_name, ... ) ]  {VALUES | VALUE}({expr |default}, ... ), (...), .. ...

  9. MySQL中的insert ignore into, replace into用法总结

    MySQL replace into 有三种形式: 1. replace into tbl_name(col_name, ...) values(...) 2. replace into tbl_na ...

随机推荐

  1. Bootstrap文本对齐风格

    在排版中离不开文本的对齐方式.在CSS中常常使用text-align来实现文本的对齐风格的设置.其中主要有四种风格: ☑  左对齐,取值left ☑  居中对齐,取值center ☑  右对齐,取值r ...

  2. ftp断点续传

    有时候ftp的文件太大了 容易断掉 使用shell下载 1 #!/bin/bash 2 cd /data2/GATK2/refSeqDB/1000genomePhase3 3 ftp -v -n 19 ...

  3. 按键精灵 句柄 获得句柄 控制windows窗口 后台

    新建一个文本文档,打开,Windows就会给这个文本文档的窗口临时分配唯一的一串数字来标识这个窗体,以区别于其他窗口,这串数字就叫句柄.   因为句柄是临时随机分配的,所以每次虽然是打开同一个文件,但 ...

  4. eclipse ssh连接sqlserver express

    public static String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; public stati ...

  5. Java多线程基础:进程和线程之由来

    转载: Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够 ...

  6. 七天学会NodeJS (原生NodeJS 学习资料 来自淘宝技术团队)

    NodeJS基础 什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充当了解析器的角色.而对于需要独立运行的JS,NodeJS就是一个解析器. ...

  7. 谈谈JPA-02-HelloWorld

    使用JPA持久化对象的步骤 创建 persistence.xml, 在这个文件中配置持久化单元 需要指定跟哪个数据库进行交互; 需要指定 JPA 使用哪个持久化的框架以及配置该框架的基本属性 创建实体 ...

  8. 《javascript高级程序设计》 第23章 离线应用与客户端存储

    23.1 离线检测23.2 应用缓存23.3 数据存储 23.3.1 Cookie 23.3.2 IE 用户数据 23.3.3 Web 存储机制 23.3.4 IndexedDB   23.1 离线检 ...

  9. ABAP-smartform-一页3列的条码打印

    1.自建barcode: se73->System bar code->change->create->new input the name of the bar code y ...

  10. jQuery性能优化指南(转载)

    现在jquery应用的越来越多, 有些同学在享受爽快淋漓coding时就将性能问题忽略了, 比如我. jquery虽在诸多的js类库中性能表现还算优秀, 但毕竟不是在用原生的javascript开发, ...