`

转关于mysql5.5 的批处理讨论(转载)

阅读更多

MySql的JDBC驱动不支持批量操作(已结)

http://www.iteye.com/topic/770032

 

 

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代码 复制代码 收藏代码
  1. System.out.println("before executeBatch. "+ (System.currentTimeMillis()-a)+" ms");   
  2. prest.executeBatch();   
  3. System.out.println("before commit. "+ (System.currentTimeMillis()-a)+" ms");   
  4. 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代码 复制代码 收藏代码
  1. before executeBatch. 279 ms   
  2. before commit. 7922 ms   
  3. MySql批量插入10万条记录用时7923 ms  

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代码 复制代码 收藏代码
  1. try {   
  2.     clearWarnings();   
  3.   
  4.     if (!this.batchHasPlainStatements   
  5.             && this.connection.getRewriteBatchedStatements()) {   
  6.            
  7.            
  8.         if (canRewriteAsMultiValueInsertAtSqlLevel()) {   
  9.             return executeBatchedInserts(batchTimeout); //执行路径之一   
  10.         }   
  11.            
  12.         if (this.connection.versionMeetsMinimum(410)    
  13.                 && !this.batchHasPlainStatements   
  14.                 && this.batchedArgs != null    
  15.                 && this.batchedArgs.size() > 3 /* cost of option setting rt-wise */) {   
  16.             return executePreparedBatchAsMultiStatement(batchTimeout); //执行路径之二   
  17.         }   
  18.     }   
  19.   
  20.     return executeBatchSerially(batchTimeout); //执行路径之三   
  21. finally {   
  22.     clearBatch();   
  23. }  

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代码 复制代码 收藏代码
  1. 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代码 复制代码 收藏代码
  1. insert into t_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 就崩掉了。

分享到:
评论

相关推荐

    mysql 5.5版本的驱动

    MySQL 5.5版本的驱动是Java应用程序与MySQL数据库交互的关键组件,主要通过JDBC(Java Database Connectivity)接口实现。JDBC是Java平台上的标准,它允许Java开发者使用SQL语句来访问和处理数据库。MySQL的JDBC驱动...

    MySQL5.5绿色版(免安装)

    MySQL5.5绿色版是一款无需安装的数据库管理系统,特别适合于对系统资源有限制或者希望快速部署MySQL环境的用户。它的大小约为10MB,这使得它非常轻巧,易于在各种设备上进行快速下载和使用。解压缩后,用户可以直接...

    mysql5.5安装包、图形化界面

    MySQL 5.5是MySQL数据库管理系统的一个重要版本,它提供了许多增强的功能和性能优化,使得这个版本成为当时很多企业和开发者的首选。在这个压缩包中,包含的是MySQL 5.5的Windows 32位安装程序以及一个图形化界面...

    MySQL5.5.zip_mySql chm_mysql 5.5_mysql 中文_mysql5.5_mysql5.5.chm

    这份"MySQL5.5.zip"压缩包包含了一个名为"mysql 5.5 chm 中文手册"的文件,这是一个CHM(Compiled HTML Help)格式的文档,专门针对MySQL 5.5版本,对于学习和理解MySQL 5.5的各种特性和操作非常有帮助。 MySQL 5.5...

    java连接mysql5.5的jar包

    java连接mysql5.5的jar包 mysql-connector-java-5.1.35-bin.jar

    MySQL安装文件MySQL5.5.zip

    标题中的"MySQL安装文件MySQL5.5.zip"指的是包含MySQL 5.5版本安装程序的压缩包。这个压缩文件通常包含了安装MySQL所需的所有组件,包括服务器、客户端工具、连接器以及相关的文档。"mysql-5.5.21.msi"是MySQL ...

    MYSQL5.5英文手册,MYSQL5.5手册

    MYSQL5.5英文手册,MYSQL5.5手册,MYSQL英文手册,MYSQL手册

    MySql5.5 安装包 以及安装图解

    MySQL 5.5 是 MySQL 数据库的一个重要版本,它提供了许多增强的功能和性能优化,适合于中小型企业到大型企业的各种规模应用。以下是对这个压缩包文件中涉及的几个关键知识点的详细说明: 1. **MySQL 5.5 安装**: ...

    MySQL5.5中文版

    MySQL5.5中文版是MySQL数据库管理系统的一个重要版本,它为用户提供了稳定、高效和功能丰富的数据存储解决方案。MySQL是一个开源的关系型数据库管理系统(RDBMS),由瑞典的MySQL AB公司开发,后来被甲骨文公司收购...

    Mysql5.5安装文件,里面有安装教程

    本文将详细介绍如何安装MySQL 5.5,这是MySQL的一个稳定版本,提供了强大的数据存储和管理功能。 首先,我们来理解一下MySQL 5.5的主要特点: 1. **更高的性能**:MySQL 5.5通过InnoDB存储引擎的优化,提升了查询...

    mysql5.5安装软件

    MySQL 5.5是MySQL数据库管理系统的一个重要版本,它在2010年发布,带来了许多性能提升和新特性。MySQL是一种开源、免费的关系型数据库管理系统(RDBMS),广泛应用于网页应用程序、企业级系统以及大数据处理等领域。...

    MySQL5.5-deps

    MySQL5.5-deps是一个专为mini版Linux环境设计的压缩包,包含了在该系统上安装MySQL 5.5版本所需的所有依赖项。这个压缩包的目的是为了简化MySQL的安装过程,确保所有必要的库和软件组件都已就绪,以便MySQL能够顺利...

    mysql5.5--64位 下载安装

    MySQL 5.5是MySQL数据库管理系统的一个重要版本,尤其对于64位操作系统而言,它提供了更高的性能和稳定性。本文将详细介绍MySQL 5.5在64位系统上的下载、安装和配置过程,以及相关的技术要点。 一、MySQL 5.5的特性...

    mysql5.5安装包 Windows (x86, 64-bit)

    MySQL 5.5是MySQL数据库管理系统的一个重要版本,它在2010年发布,针对性能、稳定性以及功能进行了多项优化。本安装包是专为Windows操作系统设计的,支持32位(x86)和64位(x64)架构。MySQL 5.5在Windows平台上的...

    MySQL5.5的安装包

    MySQL 5.5是MySQL数据库管理系统的一个重要版本,它在2010年发布,带来了许多性能提升和功能增强。这个一键安装包旨在简化安装过程,让用户能够快速、简便地在计算机上设置MySQL服务器。 首先,MySQL 5.5引入了...

    MySQL 5.5+图形界面工具

    以下是一些关于 MySQL 5.5 和图形界面工具的关键知识点: 1. **MySQL 5.5 的特性**: - **InnoDB 引擎优化**:MySQL 5.5 强化了 InnoDB 存储引擎,支持全文搜索,提高了事务处理能力和并发性能。 - **更好的性能*...

    MySQL5.5.zip

    MySQL5.5是MySQL数据库系统的一个重要版本,它在2010年发布,提供了许多增强功能和性能改进。MySQL是一种流行的开源关系型数据库管理系统(RDBMS),广泛应用于Web应用、数据存储和数据分析等领域。以下是对MySQL5.5...

    mysql5.5免安装.rar

    这个“mysql5.5免安装.rar”文件是一个绿色免安装版的MySQL 5.5.22,适用于那些希望快速部署数据库而不想经历传统安装过程的用户。下面我们将详细探讨MySQL 5.5的一些关键知识点。 首先,MySQL 5.5在性能上的提升...

    Mysql5.5数据库安装包

    这个“Mysql5.5数据库安装包”包含了MySQL 5.5.12的Windows 32位版本,适合在32位操作系统上安装和运行。以下是关于MySQL 5.5的一些核心知识点: 1. **存储引擎**:MySQL 5.5默认使用InnoDB存储引擎,提供事务处理...

Global site tag (gtag.js) - Google Analytics