爲了提高插入數據的效率,我們可以利用MySql的批量插入數據能力。其實,從本質來說也就是取消JDBC中事務的自動提交,改爲手動提交。
如果沒有關閉JDBC事務的自動提交,那麼JDBC驅動會在每次執行了一條SQL語句之後,自動提交,並且關閉連接。而我們知道打開數據庫連接是非常耗資源的,而且有些JDBC框架還會限制數據庫操作的頻率。這種情況下,如果採用單調數據插入效果非常不好。
解決的方法之一,就是關閉JDBC事務的自動提交,改爲手動提交。我們可以記錄SQL語句的執行次數,然後當達到某一個值的時候,比如10w次的時候,手動提交一下事務,然後關閉並重新開始數據庫連接。再進行下一批數據局的插入或者更新。
這種方法非常適合於準備測試環境當中的大批量數據。在運行程序過程中,會碰到JVM拋出內存不足的異常,這個時候可以調大內存,或者減少每批數據的數據量來解決。
以下代碼僅供參考,在下面代碼中,每批的數據庫量爲1w條記錄。不同JDBC版本支持的批量插入的數據量不同,爲了謹慎起見,可以先改小一點,然後慢慢提高。
- @Test
- public void testInsertFollowRelation(){
- String db = "com.mysql.jdbc.Driver";
- String host = "jdbc:mysql://127.0.0.1:3306/test?characterEncoding=GBK";
- String user = "abc";
- String passwd = "abc";
- Connection con = null;
- try{
- Class.forName(db).newInstance();
- } catch (Exception e) {
- System.out.println("加載驅動失敗:" + db);
- }
- long starTime = System.currentTimeMillis();
- try {
- long startRowNum = 0;
- long count = 0;
- //使用事務插入,每10000條數據提交一下事務。
- //提高效率
- for(int i = 0; i < 10; i++){
- BufferedReader reader = new BufferedReader(new FileReader(new File("E:\\test.txt")));
- con = DriverManager.getConnection(host, user, passwd);
- con.setAutoCommit(false);
- PreparedStatement pstmt = con.prepareStatement("INSERT INTO test " +
- "(id,info) " +
- "VALUES(?,?,?,now())");
- String info = null;
- while((info= reader.readLine()) != null){
- pstmt.setLong(1, startRowNum);
- pstmt.setLong(2, info);
- pstmt.executeUpdate();
- count++;
- startRowNum ++;
- if(startRowNum % 10000 == 0){//如果數據條數達到10000條,則提交事務
- con.commit();
- con.close();
- //重開鏈接
- con = DriverManager.getConnection(host, user, passwd);
- con.setAutoCommit(false);
- pstmt = con.prepareStatement("INSERT INTO test " +
- "(id,info) " +
- "VALUES(?,?,?,now())");
- System.out.println("數據量達到10000條,提交事務完成。");
- }
- }
- reader.close();
- }
- long endTime = System.currentTimeMillis();
- System.out.println("共耗時:<" + new Float(((endTime-starTime)/1000)) + ">秒。插入了(" + count + ")條數據");
- } catch(Exception e){
- e.printStackTrace();
- try {
- con.rollback();
- } catch (SQLException e1) {
- e1.printStackTrace();
- }
- }
- }