mysql5批處理_轉關于mysql5.5 的批處理討論(轉載)

MySql的JDBC驅動不支持批量操作(已結)

MySql連接的url中要加rewriteBatchedStatements參數,例如

String?connectionUrl="jdbc:mysql://192.168.1.100:3306/test?rewriteBatchedStatements=true";

還要保證mysql JDBC驅的版本。MySql的JDBC驅動的批量插入操作性能是很優秀的。

MySql的JDBC驅動,不是真正支持批量操作的,就算你在代碼中調用了批量操作的方法,MySql的JDBC驅動也是按照一般操作來處理的。

直覺告訴我,應該是一些簡單的設置問題,事實上最后得到的結果也是如此的。

帶著解決這個疑惑的想法,依據大家之前得到的一些結果,信息,開始測試

工具:

eclipse-3.6, mysql-5.1.48, mysql-jdbc-driver 5.1.11, mysql workbench前面說過了,我直覺認為代碼不會有問題,所以先著手改善mysql 的服務器配置,innodb的設置。改了幾個參數,都沒有什么效果。加大了日志緩存,只是提高到7000多毫秒。最后甚至很多歪門邪道的設置都大膽用了,一度讓mysql 無法啟動。。。最終都收效甚微,這個步驟大概試了將近一個小時。

這條路看來是走不通了。。得尋找別的方法

冷靜下來想想,其實從代碼中應該是可以發現些端倪

樓主的非batch代碼中,每次調用 execute() 其實是會通過網絡發送一條語句到服務器端的,是不會在客戶端排隊攢著的。

因為這個方法必須返回一個結果。它必然跟服務器發生了一次交互。

而在batch處理的代碼中,其addBatch 就是無返回值,它提供了一個可能就是在客戶端將語句緩存排隊攢著,最后executeBatch時才發送到服務器端。

用代碼可以證明,在batch處理方法的代碼中,在 executeBatch, 及 commit 方法執行前,分別安插兩條打印時間語句:

Java代碼d7d454600f77758df47d870acbf00b9c.png7a1e7afc0f2addbbdb746966b60e9e4a.png

ffb34937a6f01b9d5cc633a2ffcdf885.png

System.out.println("before?executeBatch.?"+?(System.currentTimeMillis()-a)+"?ms");

prest.executeBatch();

System.out.println("before?commit.?"+?(System.currentTimeMillis()-a)+"?ms");

conn.commit();

System.out.println("before executeBatch. "+ (System.currentTimeMillis()-a)+" ms"); prest.executeBatch(); System.out.println("before commit. "+ (System.currentTimeMillis()-a)+" ms"); conn.commit();

在我機器上的結果是,

Java代碼d7d454600f77758df47d870acbf00b9c.png7a1e7afc0f2addbbdb746966b60e9e4a.png

ffb34937a6f01b9d5cc633a2ffcdf885.png

before?executeBatch.279ms

before?commit.7922ms

MySql批量插入10萬條記錄用時7923ms

before executeBatch. 279 ms before commit. 7922 ms MySql批量插入10萬條記錄用時7923 ms

說明客戶端在攢語句時,相當的快,279毫秒就完成了,但在 executeBatch 這個方法的調用過程中,花費了 7920? 減 去 279 的毫秒數。大部分都耗在這里了。 最后提交事務非常快,1毫秒而已

想想看,前邊說過,非batch和batch的處理幾乎是一樣的時間。

可不可以先假設 batch 的方式與非batch一樣,每一條insrt語句事實上均是單獨發往服務器的呢?

瀏覽下源代碼吧。

好幾位兄弟都描述了源代碼,直接從那幾個類入手吧,事實上關鍵的類是這個 com.mysql.jdbc.PreparedStatement

先看了其中的 addBatch 方法,沒有任何問題,只是將語句添加進入一個 List 中保存。

那么 executeBatch 呢?

再貼一下吧, 關鍵看其中的這部分,順帶說一下, 這個mysql-jdbcdriver的源代碼是 5.1.13的

Java代碼d7d454600f77758df47d870acbf00b9c.png7a1e7afc0f2addbbdb746966b60e9e4a.png

ffb34937a6f01b9d5cc633a2ffcdf885.png

try{

clearWarnings();

if(!this.batchHasPlainStatements

&&this.connection.getRewriteBatchedStatements())?{

if(canRewriteAsMultiValueInsertAtSqlLevel())?{

returnexecuteBatchedInserts(batchTimeout);//執行路徑之一

}

if(this.connection.versionMeetsMinimum(4,1,0)

&&?!this.batchHasPlainStatements

&&this.batchedArgs?!=null

&&this.batchedArgs.size()?>3/*?cost?of?option?setting?rt-wise?*/)?{

returnexecutePreparedBatchAsMultiStatement(batchTimeout);//執行路徑之二

}

}

returnexecuteBatchSerially(batchTimeout);//執行路徑之三

}finally{

clearBatch();

}

try { clearWarnings(); if (!this.batchHasPlainStatements && this.connection.getRewriteBatchedStatements()) { if (canRewriteAsMultiValueInsertAtSqlLevel()) { return executeBatchedInserts(batchTimeout); //執行路徑之一 } if (this.connection.versionMeetsMinimum(4, 1, 0) && !this.batchHasPlainStatements && this.batchedArgs != null && this.batchedArgs.size() > 3 /* cost of option setting rt-wise */) { return executePreparedBatchAsMultiStatement(batchTimeout); //執行路徑之二 } } return executeBatchSerially(batchTimeout); //執行路徑之三 } finally { clearBatch(); }

其實最終,executeBatch 的執行路徑有三種可能。代碼中我已標出來

不小心按了提交了,繼續編輯此回復吧。代碼不算太復雜,但是有一個參數能幫助我們更快的確定mysql的batch工作機制,那就是

mysql jdbc driver 的connection url, 其中有一個參數是: rewriteBatchedStatements

完整的參數參考看這里:http://ftp.ntu.edu.tw/ftp/pub/MySQL/doc/refman/5.1/en/connector-j-reference-configuration-properties.html

rewriteBatchedStatements 參數默認為false, 需要手工設置為true,設置方式大概像這樣:

Java代碼d7d454600f77758df47d870acbf00b9c.png7a1e7afc0f2addbbdb746966b60e9e4a.png

ffb34937a6f01b9d5cc633a2ffcdf885.png

String?connectionUrl="jdbc:mysql://192.168.1.100:3306/test?rewriteBatchedStatements=true";

String connectionUrl="jdbc:mysql://192.168.1.100:3306/test?rewriteBatchedStatements=true";

默認時候,rewriteBatchedStatements=false時,執行路徑會跳到 executeBatchSerially,此方法內部將語句一條條發送,與非batch處理簡直一樣,所以慢,就在這里了。

當設為 true時,會執行executeBatchedInserts方法,事實上mysql支持這樣的插入語句

Sql代碼d7d454600f77758df47d870acbf00b9c.png7a1e7afc0f2addbbdb746966b60e9e4a.png

ffb34937a6f01b9d5cc633a2ffcdf885.png

insertintot_user(id,uname)values(1,'1'),?(2,'2'),?(3,'3')?....

insert into t_user(id,uname) values(1, '1'), (2,'2'), (3, '3') ....

所以,當rewriteBatchedStatements=true時, 樓主的例子會被編譯為以上形式,當然values里全是?, mysql 客戶端會對這些值添加參數. 這樣的方式當然就快很多了。

其實到現在還不太了解 batch 處理時,執行計劃這個概念,不過我猜 mysql 可能并沒有緩存執行計劃。而只是將這些語句組合起來了。

所以如果是這樣,他的機制與oracle可能是有所不同的,還不是達到最高效的機制,也許這就是開源與商業的區別吧。

我們如果想更深入了解,只能借助于一些服務器端監視工具,sql分析工具了。

寫貼子過程斷斷續續給打擾了,本來還有一些可以寫更詳細的,就留給大家自己去探索了,包括,如果調用addBatch(String sql)后,則仍會按照 executeBatchSerially 方式執行,包括何時執行 executePreparedBatchAsMultiStatement,都可以繼續深入了解。

后記,當使用 update 時,會執行 executePreparedBatchAsMultiStatement,但是如果攢的語句太多,會導致 mysql 崩潰. 我的測試中10000條update不會有事,20000時,mysql 就崩掉了。

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2011-11-17 15:19

瀏覽 1569

分類:數據庫

評論

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/541475.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/541475.shtml
英文地址,請注明出處:http://en.pswp.cn/news/541475.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java Duration類| isZero()方法與示例

持續時間類isZero()方法 (Duration Class isZero() method) isZero() method is available in java.time package. isZero()方法在java.time包中可用。 isZero() method is used to check whether this Duration object holds the value of length is 0 or not. isZero()方法用…

《C#多線程編程實戰(原書第2版)》——3.2 在線程池中調用委托

本節書摘來自華章出版社《C#多線程編程實戰(原書第2版)》一書中的第3章,第3.2節,作者(美)易格恩阿格佛溫(Eugene Agafonov),黃博文 黃輝蘭 譯,更多章節內容可…

mysql語句數據庫_數據庫的Mysql語句

數據庫的mysql語句: 1.連接數據庫 mysql -u root -p2.顯示數據庫 show databases(db);3.選擇數據庫 use 數據庫名;4.顯示數據庫中的表 show tables;基本數據操作:增刪改查1.增 :insert into 表名(字段1,字段2…)values (值1,值2…);2.刪 :delete from 表名 where 條件;3.改 :up…

java clock計時_Java Clock類| systemUTC()方法與示例

java clock計時Clock Class systemUTC()方法 (Clock Class systemUTC() method) systemUTC() method is available in java.time package. systemUTC()方法在java.time包中可用。 systemUTC() method is used to get a Clock that implements the suitable system clock in the…

《Android 應用測試指南》——第2章,第2.4節包瀏覽器

本節書摘來自異步社區《Android 應用測試指南》一書中的第2章,第2.4節包瀏覽器,作者 【阿根廷】Diego Torres Milano(迭戈 D.),更多章節內容可以訪問云棲社區“異步社區”公眾號查看 2.4 包瀏覽器創建完前面提到的兩個…

操作系統系統調用_操作系統中的系統調用

操作系統系統調用系統調用簡介 (Introduction to System calls) The interface between the operating system and the user program is defined by the set of extended instruction that the operating system provides. These extended instructions are known as system ca…

java分數表示_表示Java分數的最佳方法?

小編典典碰巧的是不久前我寫了一個BigFraction類,用于解決Euler項目問題。它保留了BigInteger分子和分母,因此它將永遠不會溢出。但是,對于許多你永遠不會溢出的操作來說,這會有點慢。無論如何,請根據需要使用它。我一…

《OpenStack云計算實戰手冊(第2版)》——1.7 添加用戶

本節書摘來自異步社區《OpenStack云計算實戰手冊(第2版)》一書中的第1章,第1.7節,作者: 【英】Kevin Jackson , 【美】Cody Bunch 更多章節內容可以訪問云棲社區“異步社區”公眾號查看。 1.7 添加用戶 在OpenStack身份認證服務中…

開源軟件和自由軟件_自由和開源軟件的經濟學

開源軟件和自由軟件零邊際成本 (Zero Marginal Cost) At the core of the financial aspects of Free and Open Source is the zero negligible expense of merchandise in an environment that is digital. Right now, the rise of Free and Open Source speaks to an affirma…

java外部類_Java里什么叫內部類什么叫外部類

展開全部對普通類(沒有內部類的類)來說,62616964757a686964616fe78988e69d8331333337396234內部類和外部類都與他無關;對有內部類的類來說,它們就是其內部類的外部類,外部類是個相對的說法,其實就是有內部類的類。所以…

《精通Matlab數字圖像處理與識別》一6.2 傅立葉變換基礎知識

本節書摘來自異步社區《精通Matlab數字圖像處理與識別》一書中的第6章,第6.2節,作者 張錚 , 倪紅霞 , 苑春苗 , 楊立紅,更多章節內容可以訪問云棲社區“異步社區”公眾號查看 6.2 傅立葉變換基礎知識 精通Matlab數字圖像處理與識別要理解傅立…

多線程循環輸出abcc++_C ++循環| 查找輸出程序| 套裝5

多線程循環輸出abccProgram 1: 程序1&#xff1a; #include <iostream>using namespace std;int main(){int num 15673;int R1 0, R2 0;do {R1 num % 10;R2 R2 * 10 R1;num num / 10;} while (num > 0);cout << R2 << " ";return 0;}Ou…

java oql_深入理解java虛擬機(八):java內存分析工具-MAT和OQL

以下內容翻譯自MAT幫助文檔。一、Class HistogramClass Histogram shows the classes found in the snapshot, the number of objects for each class, the heap memory consumption of these objects, and the minimum retained size of the objects二、Dominator treeDomina…

《Python數據分析與挖掘實戰》一1.2 從餐飲服務到數據挖掘

本節書摘來自華章出版社《Python數據分析與挖掘實戰》一書中的第1章&#xff0c;第1.2節&#xff0c;作者 張良均 王路 譚立云 蘇劍林&#xff0c;更多章節內容可以訪問云棲社區“華章計算機”公眾號查看 1.2 從餐飲服務到數據挖掘 企業經營最大的目的就是盈利&#xff0c;而餐…

obj[]與obj._Ruby中帶有示例的Array.include?(obj)方法

obj[]與obj.Ruby Array.include&#xff1f;(obj)方法 (Ruby Array.include?(obj) Method) In the previous articles, we have seen how we can check whether two Array instances are identical or not with the help of <> operator, operator, and .eql? method?…

java javah_Java開發網 - 一個javah的問題

Posted by:jerry_xuPosted on:2006-03-13 15:39我在環境變量中已經設置了path為D:\Program Files\Java\jdk1.5.0_06&#xff0c;ClassPath設置為.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;class的路徑為&#xff1a;D:\JNItest\bin\jni\Hello.class &#xff0c;但是…

《Python面向對象編程指南》——2.7 __del__()方法

本節書摘來自異步社區《Python面向對象編程指南》一書中的第2章&#xff0c;第2.7節&#xff0c;作者&#xff3b;美&#xff3d;Steven F. Lott&#xff0c; 張心韜 蘭亮 譯&#xff0c;更多章節內容可以訪問云棲社區“異步社區”公眾號查看。 2.7 __del__()方法 __del__()方…

NullReferenceException C#中的異常

什么是NullReferenceException&#xff1f; (What is NullReferenceException?) NullReferenceException is an exception and it throws when the code is trying to access a reference that is not referencing to any object. If a reference variable/object is not refe…

java map key 大寫轉小寫_Spring JdbcTemplate 查詢出的Map,是如何產生大小寫忽略的Key的?(轉)...

Java 是區分大小寫的&#xff0c;普通的Map例如HashMap如果其中的key"ABC" value"XXX"那么map.get("Abc") 或 map.get("abc")是獲取不到值得。但Spring中產生了一個忽略大小寫的map使我產生了好奇例如 jdbcTemplate.queryForList(sql)…

《iOS 6核心開發手冊(第4版)》——2.11節秘訣:構建星星滑塊

本節書摘來自異步社區《iOS 6核心開發手冊&#xff08;第4版&#xff09;》一書中的第2章&#xff0c;第2.11節秘訣&#xff1a;構建星星滑塊&#xff0c;作者 【美】Erica Sadun&#xff0c;更多章節內容可以訪問云棲社區“異步社區”公眾號查看 2.11 秘訣&#xff1a;構建星星…