首页
学习
活动
专区
圈层
工具
发布

10亿数据如何最快速插入MySQL?

我跟你说啊,这事儿其实就是上周在工位那会儿聊起来的,我们组那个老朱,搞个ETL导入任务,硬是跑了一晚上,插了不到一个亿的数据,还美滋滋地说“还行”。我听了直接脑瓜子嗡嗡的,你说你搞MySQL,插入慢成那样,还不赶紧看看方案?

不要天真地一条条插,批量才是王道

你别跟我说什么for循环一条条insert,那是给小作坊写脚本的。我看了老朱的代码,典型的:

for (int i = 0; i < data.size(); i++) {

  String sql = "INSERT INTO big_table (col1, col2) VALUES (?, ?)";

  PreparedStatement stmt = conn.prepareStatement(sql);

  stmt.setString(1, data.get(i).getCol1());

  stmt.setString(2, data.get(i).getCol2());

  stmt.executeUpdate();

}

我当场就说:“哥你这样能快我直播吃键盘”,不是说你写得不对啊,是你这思路就有问题。

JDBC批处理,最低配也得整这个

我们当时就现场改,用addBatch()配合executeBatch(),这玩意跟吃药似的,整瓶吃才有效。

Connection conn = dataSource.getConnection();

conn.setAutoCommit(false);

PreparedStatement stmt = conn.prepareStatement("INSERT INTO big_table (col1, col2) VALUES (?, ?)");

for (int i = 0; i < data.size(); i++) {

  stmt.setString(1, data.get(i).getCol1());

  stmt.setString(2, data.get(i).getCol2());

  stmt.addBatch();

  if (i % 10000 == 0) {

      stmt.executeBatch();

      conn.commit(); // 不commit等着吃内存炸弹吧

      stmt.clearBatch();

  }

}

stmt.executeBatch();

conn.commit();

stmt.close();

conn.close();

我们改完那套代码之后,一晚上能插4亿多,那速度,老朱第二天都开始考虑换工作了。

更极限一点?直接写CSV文件导入

这个是真的骚操作。有时候你要插的是真·亿级数据,这种JDBC插法哪怕批处理都嫌慢,那就别装了,乖乖走LOAD DATA INFILE:

LOAD DATA INFILE '/path/to/data.csv'

INTO TABLE big_table

FIELDS TERMINATED BY ','

ENCLOSED BY '"'

LINES TERMINATED BY '\n'

(col1, col2);

你Java这边就输出CSV,随便用个BufferedWriter拼:

BufferedWriter writer = new BufferedWriter(new FileWriter("data.csv"));

for (MyData item : data) {

  writer.write(item.getCol1() + "," + item.getCol2());

  writer.newLine();

}

writer.close();

这个方式我们测过,一小时导10亿不是梦,MySQL自己把CSV吞了,那才是数据库真正擅长的事情。

不要忘了关掉你不该开的东西

对,还有个坑,很多人忘了插数据前关日志、关索引。你一边建索引一边插,那就不是插数据,是在杀服务器。

ALTER TABLE big_table DISABLE KEYS;

-- 然后导入

ALTER TABLE big_table ENABLE KEYS;

还有binlog、foreign key、autocommit啥的,能关的先关,记得导完再开,不然插一行卡半秒。

最后一句:MySQL不是万能的

我说真的,如果你每天都得干这种10亿数据的活儿,你是不是该考虑用ClickHouse或者专门搞个Kafka + Flink + Hive那套玩意了?老朱最后都去问大数据组借机器了,人家直接说一句“为啥不用Hudi?”他当场脸绿。

行了,先聊到这,我这会儿去泡杯咖啡,一会儿还有个工单要看,你们要是实在插不进去,回头来我桌上,咱们抠SQL调内核一起看。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OrDd_ZHelA2kfIHXbaIRFs7w0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券