当前位置:   article > 正文

mysql batch insert_batch insert 1 million datas into mysql

mysql batch insert

最近尝试插入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个问题:

在DB端,每次执行都会以1个单独的事务执行;

在网络上,传输的次数过多、每次传输的效率较差。

相应的解决方法是:

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

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

insert into table (fields...) values (1...), (2...), ... , (10000...);

可以修改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的源码,如果你有更快的方法,不妨留言~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/pgrmghi/article/detail/61844
推荐阅读
相关标签
  

闽ICP备14008679号