三種JDBC批量插入編程方法的比較

JDBC批量插入主要用於數據導入和日誌記錄因爲日誌一般都是先寫在文件下的等。
我用Mysql 5.1.5的JDBC driver 分別對三種比較常用的方法做了測試

[list]
[*]方法一,使用PreparedStatement加批量的方法
[/list]
 
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(o_url, userName, password);
conn.setAutoCommit(false);
String sql = "INSERT adlogs(ip,website,yyyymmdd,hour,object_id) VALUES(?,?,?,?,?)";
PreparedStatement prest = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
for(int x = 0; x < size; x++){
prest.setString(1, "192.168.1.1");
prest.setString(2, "localhost");
prest.setString(3, "20081009");
prest.setInt(4, 8);
prest.setString(5, "11111111");
prest.addBatch();
}
prest.executeBatch();
conn.commit();
conn.close();
} catch (SQLException ex) {
Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null, ex);
}

說明下在建Statement的時候,後面兩個參數的意義:
第一個參數指定 ResultSet 的類型。其選項有:
[b]TYPE_FORWARD_ONLY[/b]:缺省類型。只允許向前訪問一次,並且不會受到其他用戶對該數據庫所作更改的影響。
[b]TYPE_SCROLL_INSENSITIVE[/b]:允許在列表中向前或向後移動,甚至可以進行特定定位,例如移至列表中的第四個記錄或者從當前位置向後移動兩個記錄。不會受到其他用戶對該數據庫所作更改的影響。
[b]TYPE_SCROLL_SENSITIVE[/b]:象 TYPE_SCROLL_INSENSITIVE 一樣,允許在記錄中定位。這種類型受到其他用戶所作更改的影響。如果用戶在執行完查詢之後刪除一個記錄,那個記錄將從 ResultSet 中消失。類似的,對數據值的更改也將反映在 ResultSet 中。
第二個參數設置 ResultSet 的併發性,該參數確定是否可以更新 ResultSet。其選項有:
[b]CONCUR_READ_ONLY[/b]:這是缺省值,指定不可以更新
[b]ResultSet CONCUR_UPDATABLE[/b]:指定可以更新 ResultSet

[list]
[*]方法二 使用Statement加批量的方法
[/list]
 
conn.setAutoCommit(false);
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
for(int x = 0; x < size; x++){
stmt.addBatch("INSERT INTO adlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3', 'localhost','20081009',8,'23123')");
}
stmt.executeBatch();
conn.commit();


[list]
[*]方法三:直接使用Statement
[/list]

conn.setAutoCommit(false);
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
for(int x = 0; x < size; x++){
stmt.execute("INSERT INTO adlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3', 'localhost','20081009',8,'23123')");
}
conn.commit();


使用上述方法分別插入10萬條數據的平均測試時間爲:
方法一:[b]17.844[/b]s
方法二:[b]18.421[/b]s
方法三:[b]16.359[/b]s

可以看出JDBC的batch語句插入不但沒有性能提升,反而比沒有用batch的時候要慢,當然這可能跟JDBC具體驅動的實現方法有關。 附件中是我測試代碼,可以用來在自己電腦上跑一下。

在執行批量插入的時候最主要的是將自動提交取消,這樣不管是否用JDBC的batch語法應該都沒有關係。
conn.setAutoCommit(false)


個人覺得第一種方法是最方便最實用的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章