MySQL Jdbc驅動在默認狀況下會無視executeBatch()語句,把咱們指望批量執行的一組sql語句拆散,一條一條地發給MySQL數據庫,直接形成較低的性能。mysql
只有把rewriteBatchedStatements參數置爲true, 驅動纔會幫你批量執行SQL (jdbc:mysql://ip:port/db?rewriteBatchedStatements=true)。不過,驅動具體是怎麼樣批量執行的? 你是否是須要看一下內幕,纔敢放心地使用這個選項? 下文會給出答案。sql
另外,有人說rewriteBatchedStatements只對INSERT有效,有人說它對UPDATE/DELETE也有效。爲此我作了一些實驗(詳見下文),結論是: 這個選項對INSERT/UPDATE/DELETE都有效,只不過對INSERT它爲會預先重排一下SQL語句。數據庫
注:本文使用的mysql驅動版本是5.1.12ide
實驗記錄:未打開rewriteBatchedStatements時性能
未打開rewriteBatchedStatements時,根據wireshark嗅探出的mysql報文能夠看出,spa
batchDelete(10條記錄) => 發送10次delete 請求blog
batchUpdate(10條記錄) => 發送10次update 請求ip
batchInsert(10條記錄) => 發送10次insert 請求文檔
也就是說,batchXXX()的確不起做用get
打開rewriteBatchedStatements後,根據wireshark嗅探出的mysql報文能夠看出
batchDelete(10條記錄) => 發送一次請求,內容爲」delete from t where id = 1; delete from t where id = 2; delete from t where id = 3; ….」
batchUpdate(10條記錄) => 發送一次請求,內容爲」update t set … where id = 1; update t set … where id = 2; update t set … where id = 3 …」
batchInsert(10條記錄) => 發送一次請求,內容爲」insert into t (…) values (…) , (…), (…)」
對delete和update,驅動所作的事就是把多條sql語句累積起來再一次性發出去;而對於insert,驅動則會把多條sql語句重寫成一條風格很酷的sql語句,而後再發出去。 官方文檔說,這種insert寫法能夠提升性能(」This is considerably faster (many times faster in some cases) than using separate single-row INSERT statements」)
須要注意的是,即便rewriteBatchedStatements=true, batchDelete()和batchUpdate()也不必定會走批量: 當batchSize <= 3時,驅動會寧願一條一條地執行SQL。因此,若是你想驗證rewriteBatchedStatements在你的系統裏是否已經生效,記得要使用較大的batch.
最後能夠看下對應的MySQL JDBC驅動的代碼,以加深印象: