使用JDBC連接MySQL數(shù)據(jù)庫(kù)進(jìn)行數(shù)據(jù)插入的時(shí)候,特別是大批量數(shù)據(jù)連續(xù)插入(100000),如何提高效率呢?
在JDBC編程接口中Statement 有兩個(gè)方法特別值得注意:
通過使用addBatch()
和executeBatch()
這一對(duì)方法可以實(shí)現(xiàn)批量處理數(shù)據(jù)。
不過值得注意的是,首先需要在數(shù)據(jù)庫(kù)鏈接中設(shè)置手動(dòng)提交,connection.setAutoCommit(false)
,然后在執(zhí)行Statement之后執(zhí)行connection.commit()
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
import java.io.BufferedReader; import java.io.IOException; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Date; import com.mysql.jdbc.Connection; public class MysqlBatchUtil { private String sql= "INSERT INTO db_test (param1,param2,param3,param4,param5) VALUES (?,?,?,?,?)" ; private String charset= "utf-8" ; private String connectStr= "jdbc:mysql://localhost:3306/test" ; private String username= "root" ; private String password= "123456" ; private void doStore() throws ClassNotFoundException, SQLException, IOException { Class.forName( "com.mysql.jdbc.Driver" ); connectStr += "?useServerPrepStmts=false&rewriteBatchedStatements=true" ; //此處是測(cè)試高效批次插入,去掉之后執(zhí)行時(shí)普通批次插入 Connection conn = (Connection) DriverManager.getConnection(connectStr, username,password); conn.setAutoCommit( false ); // 設(shè)置手動(dòng)提交 int count = 0 ; PreparedStatement psts = conn.prepareStatement(sql); String line = null ; Date begin= new Date(); for ( int i= 0 ;i<= 100000 ;i++){ psts.setString( 1 , i+ "param1" ); psts.setString( 2 , i+ "param2" ); psts.setString( 3 , i+ "param3" ); psts.setString( 4 , i+ "param4" ); psts.setString( 5 , i+ "param5" ); psts.addBatch(); // 加入批量處理 count++; } psts.executeBatch(); // 執(zhí)行批量處理 conn.commit(); // 提交 Date end= new Date(); System.out.println( "數(shù)量=" +count); System.out.println( "運(yùn)行時(shí)間=" +(end.getTime()-begin.getTime())); conn.close(); } public static void main(String[] args) { try { new MysqlBatchUtil().doStore(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } |
測(cè)試結(jié)果:
數(shù)量=100001
運(yùn)行時(shí)間=4725
一共10W,執(zhí)行時(shí)間一共花費(fèi) 47 秒.
這個(gè)效率仍然不高,似乎沒有達(dá)到想要的效果,需要進(jìn)一步改進(jìn)。
在MySQL JDBC連接字符串中還可以加入?yún)?shù),
1
|
rewriteBatchedStatements= true |
mysql默認(rèn)關(guān)閉了batch處理,通過此參數(shù)進(jìn)行打開,這個(gè)參數(shù)可以重寫向數(shù)據(jù)庫(kù)提交的SQL語(yǔ)句
1
|
useServerPrepStmts= false |
如果不開啟(useServerPrepStmts=false),使用com.mysql.jdbc.PreparedStatement進(jìn)行本地SQL拼裝,最后送到db上就是已經(jīng)替換了?后的最終SQL.
在此稍加改進(jìn),連接字符串中加入下面語(yǔ)句(代碼構(gòu)造方法中去掉注釋):
1
|
connectStr += "?useServerPrepStmts=false&rewriteBatchedStatements=true" ; |
再次測(cè)試結(jié)果如下:
數(shù)量=100001
運(yùn)行時(shí)間=1213
同樣的數(shù)據(jù)量,這次執(zhí)行只花費(fèi)了12秒 ,由此可見處理效率大大提高,呵呵
以上所述是小編給大家介紹的Java使用JDBC向MySQL數(shù)據(jù)庫(kù)批次插入10W條數(shù)據(jù)測(cè)試效率,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!
原文鏈接:http://www.cnblogs.com/wangyayun/archive/2016/12/29/6231832.html