欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

JDBC批量Insert深度優化(有事務)

系統 2058 0

JDBC批量Insert深度優化(有事務)
?
環境:
MySQL 5.1
RedHat Linux AS 5
JavaSE 1.5
DbConnectionBroker 微型數據庫連接池
?
測試的方案:
執行10萬次Insert語句,使用不同方式。
?
A組:靜態SQL,自動提交,沒事務控制(MyISAM引擎)
1、逐條執行10萬次
2、分批執行將10萬分成m批,每批n條,分多種分批方案來執行。
?
B組:預編譯模式SQL,自動提交,沒事務控制(MyISAM引擎)
1、逐條執行10萬次
2、分批執行將10萬分成m批,每批n條,分多種分批方案來執行。
-------------------------------------------------------------------------------------------
C組:靜態SQL,不自動提交,有事務控制(InnoDB引擎)
1、逐條執行10萬次
2、分批執行將10萬分成m批,每批n條,分多種分批方案來執行。
?
D組:預編譯模式SQL,不自動提交,有事務控制(InnoDB引擎)
1、逐條執行10萬次
2、分批執行將10萬分成m批,每批n條,分多種分批方案來執行。
?
本次主要測試C、D組,并得出測試結果。
?
SQL代碼
DROP ? TABLE ? IF ? EXISTS ? tuser; ?

CREATE ? TABLE ? tuser ( ?
????id ? bigint (20) ? NOT ? NULL ? AUTO_INCREMENT, ?
???? name ? varchar (12) ? DEFAULT ? NULL , ?
????remark ? varchar (24) ? DEFAULT ? NULL , ?
????createtime ? datetime ? DEFAULT ? NULL , ?
????updatetime ? datetime ? DEFAULT ? NULL , ?
???? PRIMARY ? KEY ? (id) ?
) ENGINE=InnoDB AUTO_INCREMENT=1 ? DEFAULT ? CHARSET=utf8;
?
C、D組測試代碼:
package ? testbatch; ?

import ? java.io.IOException; ?
import ? java.sql.*; ?

/** ?
* JDBC批量Insert優化(下) ?
* ?
* @author leizhimin 2009-7-29 10:03:10 ?
*/
?
public ? class ? TestBatch { ?
???????? public ? static ? DbConnectionBroker myBroker = ? null ; ?

???????? static ? { ?
???????????????? try ? { ?
????????????????????????myBroker = ? new ? DbConnectionBroker( "com.mysql.jdbc.Driver" , ?
???????????????????????????????????????? "jdbc:mysql: //192.168.104.163:3306/testdb", ?
???????????????????????????????????????? "vcom" , ? "vcom" , 2, 4, ?
???????????????????????????????????????? "c:\\testdb.log" , 0.01); ?
????????????????} ? catch ? (IOException e) { ?
????????????????????????e.printStackTrace(); ?
????????????????} ?
????????} ?

???????? /** ?
???????? * 初始化測試環境 ?
???????? * ?
???????? * @throws SQLException 異常時拋出 ?
???????? */
?
???????? public ? static ? void ? init() ? throws ? SQLException { ?
????????????????Connection conn = myBroker.getConnection(); ?
????????????????conn.setAutoCommit( false ); ?
????????????????Statement stmt = conn.createStatement(); ?
????????????????stmt.addBatch( "DROP TABLE IF EXISTS tuser" ); ?
????????????????stmt.addBatch( "CREATE TABLE tuser (\n" ? + ?
???????????????????????????????? "????id bigint(20) NOT NULL AUTO_INCREMENT,\n" ? + ?
???????????????????????????????? "????name varchar(12) DEFAULT NULL,\n" ? + ?
???????????????????????????????? "????remark varchar(24) DEFAULT NULL,\n" ? + ?
???????????????????????????????? "????createtime datetime DEFAULT NULL,\n" ? + ?
???????????????????????????????? "????updatetime datetime DEFAULT NULL,\n" ? + ?
???????????????????????????????? "????PRIMARY KEY (id)\n" ? + ?
???????????????????????????????? ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8" ); ?
????????????????stmt.executeBatch(); ?
????????????????conn.commit(); ?
????????????????myBroker.freeConnection(conn); ?
????????} ?

???????? /** ?
???????? * 100000條靜態SQL插入 ?
???????? * ?
???????? * @throws Exception 異常時拋出 ?
???????? */
?
???????? public ? static ? void ? testInsert() ? throws ? Exception { ?
????????????????init();???????? ? //初始化環境 ?
????????????????Long start = System.currentTimeMillis(); ?
???????????????? for ? ( int ? i = 0; i < 100000; i++) { ?
????????????????????????String sql = ? "\n" ? + ?
???????????????????????????????????????? "insert into testdb.tuser \n" ? + ?
???????????????????????????????????????? "\t(name, \n" ? + ?
???????????????????????????????????????? "\tremark, \n" ? + ?
???????????????????????????????????????? "\tcreatetime, \n" ? + ?
???????????????????????????????????????? "\tupdatetime\n" ? + ?
???????????????????????????????????????? "\t)\n" ? + ?
???????????????????????????????????????? "\tvalues\n" ? + ?
???????????????????????????????????????? "\t('" ? + RandomToolkit.generateString(12) + ? "', \n" ? + ?
???????????????????????????????????????? "\t'" ? + RandomToolkit.generateString(24) + ? "', \n" ? + ?
???????????????????????????????????????? "\tnow(), \n" ? + ?
???????????????????????????????????????? "\tnow()\n" ? + ?
???????????????????????????????????????? ")" ; ?
????????????????????????Connection conn = myBroker.getConnection(); ?
????????????????????????conn.setAutoCommit( false ); ?
????????????????????????Statement stmt = conn.createStatement(); ?
????????????????????????stmt.execute(sql); ?
????????????????????????conn.commit(); ?
????????????????????????myBroker.freeConnection(conn); ?
????????????????} ?
????????????????Long end = System.currentTimeMillis(); ?
????????????????System.out.println( "單條執行100000條Insert操作,共耗時:" ? + (end - start) / 1000f + ? "秒!" ); ?
????????} ?

???????? /** ?
???????? * 批處理執行靜態SQL測試 ?
???????? * ?
???????? * @param m 批次 ?
???????? * @param n 每批數量 ?
???????? * @throws Exception 異常時拋出 ?
???????? */
?
???????? public ? static ? void ? testInsertBatch( int ? m, ? int ? n) ? throws ? Exception { ?
????????????????init();???????????? ? //初始化環境 ?
????????????????Long start = System.currentTimeMillis(); ?
???????????????? for ? ( int ? i = 0; i < m; i++) { ?
???????????????????????? //從池中獲取連接 ?
????????????????????????Connection conn = myBroker.getConnection(); ?
????????????????????????conn.setAutoCommit( false ); ?
????????????????????????Statement stmt = conn.createStatement(); ?
???????????????????????? for ? ( int ? k = 0; k < n; k++) { ?
????????????????????????????????String sql = ? "\n" ? + ?
???????????????????????????????????????????????? "insert into testdb.tuser \n" ? + ?
???????????????????????????????????????????????? "\t(name, \n" ? + ?
???????????????????????????????????????????????? "\tremark, \n" ? + ?
???????????????????????????????????????????????? "\tcreatetime, \n" ? + ?
???????????????????????????????????????????????? "\tupdatetime\n" ? + ?
???????????????????????????????????????????????? "\t)\n" ? + ?
???????????????????????????????????????????????? "\tvalues\n" ? + ?
???????????????????????????????????????????????? "\t('" ? + RandomToolkit.generateString(12) + ? "', \n" ? + ?
???????????????????????????????????????????????? "\t'" ? + RandomToolkit.generateString(24) + ? "', \n" ? + ?
???????????????????????????????????????????????? "\tnow(), \n" ? + ?
???????????????????????????????????????????????? "\tnow()\n" ? + ?
???????????????????????????????????????????????? ")" ; ?
???????????????????????????????? //加入批處理 ?
????????????????????????????????stmt.addBatch(sql); ?
????????????????????????} ?
????????????????????????stmt.executeBatch();???? //執行批處理 ?
????????????????????????conn.commit(); ?
//????????????????????????stmt.clearBatch();????????//清理批處理 ?
????????????????????????stmt.close(); ?
????????????????????????myBroker.freeConnection(conn); ? //連接歸池 ?
????????????????} ?
????????????????Long end = System.currentTimeMillis(); ?
????????????????System.out.println( "批量執行" ? + m + ? "*" ? + n + ? "=" ? + m * n + ? "條Insert操作,共耗時:" ? + (end - start) / 1000f + ? "秒!" ); ?
????????} ?

???????? /** ?
???????? * 100000條預定義SQL插入 ?
???????? * ?
???????? * @throws Exception 異常時拋出 ?
???????? */
?
???????? public ? static ? void ? testInsert2() ? throws ? Exception {???? ? //單條執行100000條Insert操作,共耗時:40.422秒! ?
????????????????init();???????? ? //初始化環境 ?
????????????????Long start = System.currentTimeMillis(); ?
????????????????String sql = "" + ?
???????????????????????????????? "insert into testdb.tuser\n" ? + ?
???????????????????????????????? "????(name, remark, createtime, updatetime)\n" ? + ?
???????????????????????????????? "values\n" ? + ?
???????????????????????????????? "????(?, ?, ?, ?)" ; ?
???????????????? for ? ( int ? i = 0; i < 100000; i++) { ?
????????????????????????Connection conn = myBroker.getConnection(); ?
????????????????????????conn.setAutoCommit( false ); ?
????????????????????????PreparedStatement pstmt = conn.prepareStatement(sql); ?
????????????????????????pstmt.setString(1, RandomToolkit.generateString(12)); ?
????????????????????????pstmt.setString(2, RandomToolkit.generateString(24)); ?
????????????????????????pstmt.setDate(3, ? new ? Date(System.currentTimeMillis())); ?
????????????????????????pstmt.setDate(4, ? new ? Date(System.currentTimeMillis())); ?
????????????????????????pstmt.executeUpdate(); ?
????????????????????????conn.commit(); ?
????????????????????????pstmt.close(); ?
????????????????????????myBroker.freeConnection(conn); ?
????????????????} ?
????????????????Long end = System.currentTimeMillis(); ?
????????????????System.out.println( "單條執行100000條Insert操作,共耗時:" ? + (end - start) / 1000f + ? "秒!" ); ?
????????} ?

???????? /** ?
???????? * 批處理執行預處理SQL測試 ?
???????? * ?
???????? * @param m 批次 ?
???????? * @param n 每批數量 ?
???????? * @throws Exception 異常時拋出 ?
???????? */
?
???????? public ? static ? void ? testInsertBatch2( int ? m, ? int ? n) ? throws ? Exception { ?
????????????????init();???????????? ? //初始化環境 ?
????????????????Long start = System.currentTimeMillis(); ?
????????????????String sql = "" + ?
???????????????????????????????? "insert into testdb.tuser\n" ? + ?
???????????????????????????????? "????(name, remark, createtime, updatetime)\n" ? + ?
???????????????????????????????? "values\n" ? + ?
???????????????????????????????? "????(?, ?, ?, ?)" ; ?
???????????????? for ? ( int ? i = 0; i < m; i++) { ?
???????????????????????? //從池中獲取連接 ?
????????????????????????Connection conn = myBroker.getConnection(); ?
????????????????????????conn.setAutoCommit( false ); ?
????????????????????????PreparedStatement pstmt = conn.prepareStatement(sql); ?
???????????????????????? for ? ( int ? k = 0; k < n; k++) { ?
????????????????????????????????pstmt.setString(1, RandomToolkit.generateString(12)); ?
????????????????????????????????pstmt.setString(2, RandomToolkit.generateString(24)); ?
????????????????????????????????pstmt.setDate(3, ? new ? Date(System.currentTimeMillis())); ?
????????????????????????????????pstmt.setDate(4, ? new ? Date(System.currentTimeMillis())); ?
???????????????????????????????? //加入批處理 ?
????????????????????????????????pstmt.addBatch(); ?
????????????????????????} ?
????????????????????????pstmt.executeBatch();???? //執行批處理 ?
????????????????????????conn.commit(); ?
//????????????????????????pstmt.clearBatch();????????//清理批處理 ?
????????????????????????pstmt.close(); ?
????????????????????????myBroker.freeConnection(conn); ? //連接歸池 ?
????????????????} ?
????????????????Long end = System.currentTimeMillis(); ?
????????????????System.out.println( "批量執行" ? + m + ? "*" ? + n + ? "=" ? + m * n + ? "條Insert操作,共耗時:" ? + (end - start) / 1000f + ? "秒!" ); ?
????????} ?

???????? public ? static ? void ? main(String[] args) ? throws ? Exception { ?
????????????????init(); ?
????????????????Long start = System.currentTimeMillis(); ?
????????????????System.out.println( "--------C組測試----------" ); ?
????????????????testInsert(); ?
????????????????testInsertBatch(100, 1000); ?
????????????????testInsertBatch(250, 400); ?
????????????????testInsertBatch(400, 250); ?
????????????????testInsertBatch(500, 200); ?
????????????????testInsertBatch(1000, 100); ?
????????????????testInsertBatch(2000, 50); ?
????????????????testInsertBatch(2500, 40); ?
????????????????testInsertBatch(5000, 20); ?
????????????????Long end1 = System.currentTimeMillis(); ?
????????????????System.out.println( "C組測試過程結束,全部測試耗時:" ? + (end1 - start) / 1000f + ? "秒!" ); ?

????????????????System.out.println( "--------D組測試----------" ); ?
????????????????testInsert2(); ?
????????????????testInsertBatch2(100, 1000); ?
????????????????testInsertBatch2(250, 400); ?
????????????????testInsertBatch2(400, 250); ?
????????????????testInsertBatch2(500, 200); ?
????????????????testInsertBatch2(1000, 100); ?
????????????????testInsertBatch2(2000, 50); ?
????????????????testInsertBatch2(2500, 40); ?
????????????????testInsertBatch2(5000, 20); ?

????????????????Long end2 = System.currentTimeMillis(); ?
????????????????System.out.println( "D組測試過程結束,全部測試耗時:" ? + (end2 - end1) / 1000f + ? "秒!" ); ?
????????} ?
}
?
執行結果:
--------C組測試---------- ?
單條執行100000條Insert操作,共耗時:103.656秒! ?
批量執行100*1000=100000條Insert操作,共耗時:31.328秒! ?
批量執行250*400=100000條Insert操作,共耗時:31.406秒! ?
批量執行400*250=100000條Insert操作,共耗時:31.75秒! ?
批量執行500*200=100000條Insert操作,共耗時:31.438秒! ?
批量執行1000*100=100000條Insert操作,共耗時:31.968秒! ?
批量執行2000*50=100000條Insert操作,共耗時:32.938秒! ?
批量執行2500*40=100000條Insert操作,共耗時:33.141秒! ?
批量執行5000*20=100000條Insert操作,共耗時:35.265秒! ?
C組測試過程結束,全部測試耗時:363.656秒! ?
--------D組測試---------- ?
單條執行100000條Insert操作,共耗時:107.61秒! ?
批量執行100*1000=100000條Insert操作,共耗時:32.64秒! ?
批量執行250*400=100000條Insert操作,共耗時:32.641秒! ?
批量執行400*250=100000條Insert操作,共耗時:33.109秒! ?
批量執行500*200=100000條Insert操作,共耗時:32.859秒! ?
批量執行1000*100=100000條Insert操作,共耗時:33.547秒! ?
批量執行2000*50=100000條Insert操作,共耗時:34.312秒! ?
批量執行2500*40=100000條Insert操作,共耗時:34.672秒! ?
批量執行5000*20=100000條Insert操作,共耗時:36.672秒! ?
D組測試過程結束,全部測試耗時:378.922秒! ?
?
?
測試結果意想不到吧,最短時間竟然超過上篇。觀察整個測試結果,發現總時間很長,原因是逐條執行的效率太低了。
?
結論:
?
在本測試條件下,得出結論:
?
數據庫連接池控制下,不自動提交,事務控制(InnoDB引擎)
?
1、逐條執行的效率很低很低,盡可能避免逐條執行。
2、事務控制下,靜態SQL的效率超過預處理SQL。
3、分批的大小對效率影響挺大的,一般來說,事務控制下,分批大小在100-1000之間比較合適。
4、談到優化方式,上面的批處理就是很好的優化策略。
?
?
大總結:
?
對比上篇沒事務的測試結果,得出一個全面的結論:
?
1、連接池最基本的也是最重要的優化策略,總能大幅提高性能。
?
2、批處理在效率上總是比逐條處理有優勢,要處理的數據的記錄條數越大,批處理的優勢越明顯,批處理還有一個好處就是減少了對數據庫的鏈接次數,從而減輕數據庫的壓力。
?
3、批處理執行SQL的時候,批處理的分批的大小與數據庫的吞吐量以及硬件配置有很大關系,需要通過測試找到最佳的分批大小,一般在50-1000之間。
?
4、預處理SQL在沒事務的表上效率較高,在有實物的情況下比靜態SQL稍有不及。但預定義SQL還有個好處就是消耗的內存較少,靜態SQL串會占用大量的內存資源,容易導致內存溢出的問題。因此批量執行時候可以優先選擇預定義SQL。
?
5、在批處理執行的時候,每批執行完成后,最好顯式的調用pstmt.close()或stmt.close()方法,以便盡快釋放執行過的SQL語句,提高內存利用率。
?
6、對于有大量SELECT操作,MyISAM是更好的選擇;對于有大量INSERT和UPDATE操作的表,InnoDB效率更好。
?
7、雖然測試結果只能反映特定情況下的一些事實,以上的優化策略是普遍策略,可以明顯縮短尋找最優策略的時間,對于效率要求很高的程序,還應該做并發性等測試。
?
8、測試是件很辛苦的事情,你需要有大量的事實來證明你的優化是有效的,而不能單單憑經驗,因為每個機器的環境都不一樣,使用的方式也不同。
?

本文出自 “ 熔 巖 ” 博客,轉載請與作者聯系!

JDBC批量Insert深度優化(有事務)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 在线观看国产日韩欧美 | 人操人摸 | 日韩在线电影 | 国产一级免费视频 | 91精品国产日韩91久久久久久 | 久久福利电影 | 久久亚洲国产成人亚 | 国产免费中文字幕 | 两性午夜视频 | 国产精品久久久久久无遮挡 | 中文一区二区 | 午夜影院a | 天天干天天草 | 精品一区二区电影 | 日韩在线免费 | 免费无码毛片一区二区A片 成人18网站 | 国产成人在线一区二区 | 欧美性猛片 | 久久三区 | 啪啪在线| 91精品成人免费国产 | 久久99精品久久久久久噜噜 | 久久精品视在线观看2 | 国产福利视频在线观看 | 免费99热在线观看 | 成人全黄三级视频在线观看 | 日日a.v拍夜夜添久久免费 | 日日碰| a级毛片观看 | 国产亚洲女人久久久久久 | 亚洲伊人久久综合 | 可以看的毛片 | 男女一进一出无遮挡黄 | 夜夜夜精品视频 | 欧美综合国产精品久久丁香 | av色在线| 亚洲综合色网站 | 久久久人 | 国产日韩欧美中文字幕 | 国产免费福利视频一区二区 | 一级毛片视频播放 |