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.mzph.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;构建星星…