今天在做一個將excel數據導入數據庫的程序時,由於數據量大,准備采用jdbc的批量插入。於是用了preparedStatement.addBatch();當加入1w條數據時,再執行插入操作,preparedStatement.executeBatch()。我原以為這樣會很快,結果插入65536條數據一共花30多分鍾,完全出乎我的意料。於是問了一下同事,他們在處理這種大批量數據導入的時候是如何處理的,發現他們也是用的jdbc批量插入處理,但與我不同是:他們使用了con.setAutoCommit(false);然后再preparedStatement.executeBatch()之后,再執行con.commit();於是再試,什么叫奇跡?就是剛剛導入這些數據花了半小時,而加了這兩句話之后,現在只用了15秒鍾就完成了。於是去查查了原因,在網上發現了如下一段說明:
* When importing data into InnoDB, make sure that MySQL does not have autocommit mode enabled because that
requires a log flush to disk for every insert. To disable autocommit during your import operation, surround it with
SET autocommit and COMMIT statements:
SET autocommit=0;
... SQL import statements ...
COMMIT;
第一次,正是因為沒有setAutoCommit(false);那么對於每一條insert語句,都會產生一條log寫入磁盤,所以雖然設置了批量插入,但其效果就像單條插入一樣,導致插入速度十分緩慢。
部分代碼如下:
String sql = "insert into table *****"; con.setAutoCommit(false); ps = con.prepareStatement(sql); for(int i=1; i<65536; i++){ ps.addBatch(); // 1w條記錄插入一次 if (i % 10000 == 0){ ps.executeBatch(); con.commit(); } } // 最后插入不足1w條的數據 ps.executeBatch(); con.commit();
