MYSQL JDBC的批处理操作三种方式

标签: mysql jdbc 批处理 | 发表时间:2015-01-28 18:36 | 作者:fireinwind
出处:http://www.iteye.com

 

SQL批处理是JDBC性能优化的重要武器,经本人研究总结,批处理的用法有三种。
 
package lavasoft.jdbctest; 

import lavasoft.common.DBToolkit; 

import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.SQLException; 
import java.sql.Statement; 

/** 
* JDBC的批量操作三种方式 

* @author leizhimin 2009-12-4 14:42:11 
*/ 
public class BatchExeSQLTest { 

        public static void main(String[] args) { 
                exeBatchStaticSQL(); 
        } 

        /** 
         * 批量执行预定义模式的SQL 
         */ 
        public static void exeBatchParparedSQL() { 
                Connection conn = null; 
                try { 
                        conn = DBToolkit.getConnection(); 
                        String sql = "insert into testdb.book (kind, name) values (?,?)"; 
                        PreparedStatement pstmt = conn.prepareStatement(sql); 
                        pstmt.setString(1, "java"); 
                        pstmt.setString(2, "jjjj"); 
                        pstmt.addBatch();                     //添加一次预定义参数 
                        pstmt.setString(1, "ccc"); 
                        pstmt.setString(2, "dddd"); 
                        pstmt.addBatch();                     //再添加一次预定义参数 
                        //批量执行预定义SQL 
                        pstmt.executeBatch(); 
                } catch (SQLException e) { 
                        e.printStackTrace(); 
                } finally { 
                        DBToolkit.closeConnection(conn); 
                } 
        } 

        /** 
         * 批量执行混合模式的SQL、有预定义的,还有静态的 
         */ 
        public static void exeBatchMixedSQL() { 
                Connection conn = null; 
                try { 
                        conn = DBToolkit.getConnection(); 
                        String sql = "insert into testdb.book (kind, name) values (?,?)"; 
                        PreparedStatement pstmt = conn.prepareStatement(sql); 
                        pstmt.setString(1, "java"); 
                        pstmt.setString(2, "jjjj"); 
                        pstmt.addBatch();    //添加一次预定义参数 
                        pstmt.setString(1, "ccc"); 
                        pstmt.setString(2, "dddd"); 
                        pstmt.addBatch();    //再添加一次预定义参数 
                        //添加一次静态SQL 
                        pstmt.addBatch("update testdb.book set kind = 'JAVA' where kind='java'"); 
                        //批量执行预定义SQL 
                        pstmt.executeBatch(); 
                } catch (SQLException e) { 
                        e.printStackTrace(); 
                } finally { 
                        DBToolkit.closeConnection(conn); 
                } 
        } 

        /** 
         * 执行批量静态的SQL 
         */ 
        public static void exeBatchStaticSQL() { 
                Connection conn = null; 
                try { 
                        conn = DBToolkit.getConnection(); 
                        Statement stmt = conn.createStatement(); 
                        //连续添加多条静态SQL 
                        stmt.addBatch("insert into testdb.book (kind, name) values ('java', 'java in aciton')"); 
                        stmt.addBatch("insert into testdb.book (kind, name) values ('c', 'c in aciton')"); 
                        stmt.addBatch("delete from testdb.book where kind ='C#'"); 
                        stmt.addBatch("update testdb.book set kind = 'JAVA' where kind='java'"); 
//                        stmt.addBatch("select count(*) from testdb.book");                //批量执行不支持Select语句 
                        //执行批量执行 
                        stmt.executeBatch(); 
                } catch (SQLException e) { 
                        e.printStackTrace(); 
                } finally { 
                        DBToolkit.closeConnection(conn); 
                } 
        } 
}
 

Mysql批量插入executeBatch的性能问题  

2011-09-14 14:54:47|  分类:  技术相关|举报|字号  订阅

 
 

移动MAS短信平台用的是Mysql 4.0.20版本。虽提供有各种接口,但DB接口相信是效率最高的。开发接口程序,使用JDBC连接,prepareStatement和executeBatch批量插入数据,然而当每批量设为200条时,耗时约7秒左右。问题出在哪里?

     SmsSent.connMysql.setAutoCommit(false);
     SmsSent.logger.debug("Mysql批量执行开始");
     SmsSent.insMysql.executeBatch();
     SmsSent.logger.debug("Mysql批量插入");
     SmsSent.connSybase.setAutoCommit(false);
     SmsSent.updSybase.executeBatch();
     SmsSent.logger.debug("Sybase批量更新");
     SmsSent.connSybase.commit();
     SmsSent.logger.debug("Sybase批量更新成功。");
     SmsSent.connMysql.commit(); //

     SmsSent.logger.debug("Mysql批量更新成功。");
     SmsSent.connMysql.setAutoCommit(true);
     SmsSent.connSybase.setAutoCommit(true);
查看日志,会发现耗时主要出现在“mysql批量执行开始”和“Mysql批量插入”之间,其余操作包括Sybase的200条语句更新都是毫秒级的。查找文档,得出以下结论:

老版Mysql的JDBC驱动中对批量更新executeBatch仍是以逐条方式进行的,这一点有网友捕捉通讯报文得以证实。虽然已经使用了预编译语句,仍会与Mysql产生200次通讯交互,由于该移动服务器不在本省,ping之有30多毫秒的延迟,200X30就是将近6秒的时间,当然如此计算并不科学,但仍能反映出问题所在。

所以结论就是200条更新的时间花费在通讯开销上。

若要解决问题需使用Mysql的JDBC驱动mysql-connector-java-5.1.13以上,此时可在连接URL中加入rewriteBatchedStatements=true 来使其缓冲后批量更新以提高性能。从网友的测试结果上来看性能提高将近10倍以上。Mysql库本身在3.1.13以上支持此参数。

悲剧的是,之前自己的测试证实Mysql 4.0.20是不支持5甚至4以上版本的JDBC驱动的(官方文档中也有注明)。本人使用的是3.1.14版驱动,加入以上参数后,并未报错,然而性能未有任何提高。

Mas升级mysql版本可能性不大,那么将程序放在Mas库所在机器上倒可以解决问题。

 


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [mysql jdbc 批处理] 推荐:

MYSQL JDBC的批处理操作三种方式

- - 数据库 - ITeye博客
SQL批处理是JDBC性能优化的重要武器,经本人研究总结,批处理的用法有三种. * JDBC的批量操作三种方式 .          * 批量执行预定义模式的SQL .                         pstmt.addBatch();                     //添加一次预定义参数 .

MySQL中关于JDBC URL几个重要参数说明

- - ITeye博客
  常用的有两个,一个是gjt(Giant Java Tree)组织提供的mysql驱动,其JDBC Driver名称(JAVA类名)为:org.gjt.mm.mysql.Driver.   详情请参见网站:http://www.gjt.org/.   或在本网站下载mysql JDBC Driver(mm.jar).

jdbc测试mysql数据库sql预解析(绑定变量)

- - CSDN博客推荐文章
jdbc测试mysql数据库sql预解析(绑定变量).         用习惯了oracle,学习mysql,想测试一下mysql绑定变量的效果. 以前看网上介绍大部份都说mysql没有sql共享池的概念,所以也不存在sql预解析或绑定变量的说法.         今天测试了一下(通过网络抓包和看服务器端sql日志的方法),发现mysql还是有sql预解析的实现.

正确使用MySQL JDBC setFetchSize()方法解决JDBC处理大结果集 java.lang.OutOfMemoryError: Java hea

- - Java - 编程语言 - ITeye博客
昨天在项目中需要对日志的查询结果进行导出功能. 日志导出功能的实现是这样的,输入查询条件,然后对查询结果进行导出. 之前的解决方案都是多次查询,然后使用limit 限制每次查询的条数. 那么能不能一次查询就把所有结果倒出来了. 于是我就使用一次查询,不使用limit分页. 结果出现 java.lang.OutOfMemoryError: Java heap space问题.

HA-JDBC -

- -
The state manager component is responsible for storing the active status of each database in the cluster, as well as any durability state.

mysql错误编号和jdbc对应的sql编号对应一览

- - CSDN博客研发管理推荐文章
作者:lzq123_1 发表于2014-11-12 13:29:10 原文链接. 阅读:82 评论:0 查看评论.

JDBC性能小贴

- - 开源软件 - ITeye博客
本文收集了一些用于提升JDBC性能的方法. Java应用或者JavaEE Web应用的性能是很重要的,尤其是数据库后端对应用的性能影响. 不知你是否经历过Java、JavaEE web应用非常慢的案例没有(处理一个简单的请求都要花上好几秒的时间用于数据库访问,分页、排序等). 下面这些贴士也许能提升Java应用的性能.

oracle的jdbc驱动

- - Oracle - 数据库 - ITeye博客
oracle的jdbc驱动主要有下面三类:.   1、JDBC OCI: oci是oracle call interface的缩写,此驱动类似于传统的ODBC 驱动. 因为它需要Oracle Call Interface and Net8,所以它需要在运行使用此驱动的JAVA程序的机器上安装客户端软件,其实主要是用到orcale客户端里以dll方式提供的oci和服务器配置.

jdbc日志,Log4jbdc-remix使用

- - 企业架构 - ITeye博客
   做项目的时候给jdbc做日志,只打印出代. 由是看看有没有给jdbc做日志的框架. 找到了log4jdbc,但是觉得还不是很理想,由是又看了看,还有一个护展插件log4jdbc-remix. 先不扯这么多,先来教大家怎么使用吧. 使用这个插件依赖4个类:log4j,slf4j-log4j,slf4j-api,log4j-remix.

JDBC事务控制管理

- - 编程语言 - ITeye博客
事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 例如:A——B转帐,对应于如下两条sql语句. 数据库默认事务是自动提交的,也就是发一条sql它就执行一条. 如果想多条sql放在一个事务中执行,则需要使用如下语句. 方式一:利用SQL语句管理事务. start transaction;--开启事务,这条语句之后的sql语句将处在一个事务当中,这些sql语句并不会立即执行.