`
sjsky
  • 浏览: 917972 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

MySQL之JDBC批量操作

    博客分类:
  • J2EE
阅读更多

   blog迁移至 :http://www.micmiu.com

 

         最近项目中需要周期性解析文本数据并把相关数据插入到MySQL数据库中,文本数据大概每小时12个,每个文件大概200M,解析后每个文件的入库数据量大概在30W左右,1小时大概360W数据。

 

         为了提高大量数据的入库效率于是想到了批处理,可是在实际测试过程中发现用批量操作后入库的效率并没有什么明显的提高,经搜索相关资料和自己的实际测试得出以下一些结论,以供大家参考。

 

一、基本结论

 

    1. 满足相应的前提条件后(见后面的详细描述 ),mysql执行批量插入大量数据的效率还是非常高的。

 

    2. 是否支持批量插入数据和表自身是否支持事务没有必要的关联关系,不过从测试结果看非事务型(MyISAM)比事务型(InnoDB)效率要高点

 

MySQL实现批量插入数据的前提条件:

  • 需要在url中添加参数rewriteBatchedStatements=true 比如:jdbc:mysql://192.168.8.150:3306/demo?rewriteBatchedStatements=true
  • MySQL的版本需要3.1.13+ 才支持参数rewriteBatchedStatements (目前基本用的都是5.0+,本人测试用的是5.0.77)
  • 需要MySQL的JDBC的驱动支持 (本人测试过mysql-connector-java-5.1.13、mysql-connector-java-5.1.16、mysql-connector-java-5.1.17均支持)

二、测试数据对比

 

测试插入10W条数据的耗时图如下:


测试对比 批量插入(ms) 普通插入(ms)
参数true
参数false 参数true 参数false
MyISAM 1633 36775 34913 43610
InnoDB 2374 42427 43531 34678

ps:

1.上表格中的参数是指URL中的 rewriteBatchedStatements

2.参数rewriteBatchedStatements 的值对普通插入是没有影响的,该参数只在批操作时有效

3.测试时同样的操作耗时有浮动的,普通操作大概在36-45秒之间(这里是贴出只是某一次的完成测试结果),

   本次测试的重点是关注批量插入和普通插入的效率,从上图可以明显得出结论。

 

 

从上面的数据对比图中可见:增加参数后批量插入数据的效率明显提高了很多。

 

三、测试代码如下:

 

测试建表语句:

 

CREATE TABLE `TB_TEST` (
  `ID` int(11) NOT NULL auto_increment,
  `NAME` varchar(20) default NULL,
  PRIMARY KEY  (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

 

java代码:JdbcInsert4MysqlDemo.java

package michael.jdbc;

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

/**
 * @blog http://sjsky.iteye.com
 * @author Michael
 */
public class JdbcInsert4MysqlDemo {

    // 批量操作参数 rewriteBatchedStatements=true
    private static String url = "jdbc:mysql://192.168.8.150:3306/demo?rewriteBatchedStatements=true";
    private static String user = "root";
    private static String password = "123456";
    private static String driver = "com.mysql.jdbc.Driver";

    /**
     * @param args
     */
    public static void main(String[] args) {

        JdbcInsert4MysqlDemo handler = new JdbcInsert4MysqlDemo();

        // handler.testMysqlInsert();

        handler.testMysqlBatchInsert();

    }

    /**
     * testMysqlBatchInsert
     */
    public void testMysqlBatchInsert() {
        long startTime = System.currentTimeMillis();

        Connection conn = null;
        PreparedStatement pstmt = null;
        String sql = "insert into TB_TEST(NAME)values(?)";
        int batchNum = 1000;
        try {
            Class.forName(driver);
            conn = DriverManager.getConnection(url, user, password);
            conn.setAutoCommit(false);
            pstmt = conn.prepareStatement(sql);
            for (int i = 1; i <= 100000; i++) {
                pstmt.setString(1, "test_" + i);
                pstmt.addBatch();
                if (i % batchNum == 0) {
                    pstmt.executeBatch();
                    conn.commit();
                }
            }
            pstmt.executeBatch();
            conn.commit();

            System.out.println("mysql 批量插入数据:100000 用时(/ms):"
                    + (System.currentTimeMillis() - startTime));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != pstmt) {
                    pstmt.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if (null != conn) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * testMysqlInsert
     */
    public void testMysqlInsert() {
        long startTime = System.currentTimeMillis();

        Connection conn = null;

        PreparedStatement pstmt = null;
        String sql = "insert into TB_TEST(NAME)values(?)";
        try {
            Class.forName(driver);
            conn = DriverManager.getConnection(url, user, password);

            conn.setAutoCommit(false);
            pstmt = conn.prepareStatement(sql);
            for (int i = 1; i <= 100000; i++) {
                pstmt.setString(1, "test_" + i);
                pstmt.execute();
            }
            conn.commit();
            System.out.println("mysql 普通插入数据:100000 用时(/ms):"
                    + (System.currentTimeMillis() - startTime));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != pstmt) {
                    pstmt.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if (null != conn) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }
    }
}

 

 

转载请注明来自:Michael's blog @ http://sjsky.iteye.com

 

-----------------------------------分 ------------------------------------隔 ------------------------------------线 --------------------------------------

 

8
3
分享到:
评论
7 楼 twoidiots 2011-12-09  
要是有博主参考的大牛的文章链接就更好了~ 不过还是很感谢,很方便的学习了~
6 楼 sjx19871109 2011-08-30  
很好~顶一个~!
5 楼 sjsky 2011-07-12  
zhuchengzzcc 写道
•MySQL的版本需要3.1.13+ 才支持参数rewriteBatchedStatements (目前基本用的都是5.0+,本人测试用的是5.0.77)

3.1.13+ 笔误了


没有明白这么仁兄的意思
4 楼 zhuchengzzcc 2011-07-12  
•MySQL的版本需要3.1.13+ 才支持参数rewriteBatchedStatements (目前基本用的都是5.0+,本人测试用的是5.0.77)

3.1.13+ 笔误了
3 楼 ycj1013321932 2011-07-09  
很好,刚才这样批量保存发愁呢,非常感谢
2 楼 sjsky 2011-07-08  
sunxiaofeng1011 写道
GOOD!

多谢支持,很多东西都是一些大牛们发现的,本人也就实际测试调优+自我小结而已
1 楼 sunxiaofeng1011 2011-07-08  
GOOD!

相关推荐

    JDBC批量插入 更新 删除等操作

    ### JDBC批量操作详解 #### 一、JDBC批量插入 JDBC(Java Database Connectivity)是Java平台中用来标准地连接数据库的技术。通过JDBC,Java应用程序可以与多种类型的数据库进行交互,实现数据的读取、写入等功能...

    Mybatis与JDBC批量插入MySQL数据库性能测试

    本文将探讨Mybatis和JDBC在批量插入MySQL数据库时的性能差异,并提供相关的测试资源。 首先,JDBC(Java Database Connectivity)是Java平台中用于与数据库交互的一种规范,它允许程序员使用SQL语句直接操作数据库...

    mysql-jdbc

    这在处理批量操作或需要原子性操作时很有用。 ```java conn.setAutoCommit(false); try { // SQL操作 conn.commit(); } catch (SQLException e) { conn.rollback(); e.printStackTrace(); } finally { conn....

    Mysql JDBC驱动 .zip_MYSQL_jdbc mysql_mysql jdbc_mysql jdbc driver_

    综上所述,MySQL JDBC驱动是Java开发者与MySQL数据库通信的重要桥梁,通过它,我们可以方便地执行SQL语句,进行数据操作。了解并熟练掌握JDBC和MySQL JDBC驱动的使用,对于任何Java开发人员来说都是必要的技能。

    jdbc批量插入大字段

    因此,"jdbc批量插入大字段"这个话题旨在探讨如何高效地通过Java JDBC来实现Blob字段的批量插入,以提高性能。 首先,我们需要了解JDBC(Java Database Connectivity),它是Java编程语言与各种数据库之间通信的...

    jdbc批量 (绝对经典)

    ### JDBC批量操作详解:效率与性能的提升策略 在数据库操作中,批量处理是一种常见的优化技术,用于提高数据处理的效率和性能。JDBC(Java Database Connectivity)作为Java应用程序与数据库交互的标准API,提供了...

    mysql的jdbc驱动5.1

    MySQL的JDBC驱动是连接Java应用程序与MySQL数据库的关键组件,它实现了Java Database Connectivity (JDBC) API,使得Java开发者能够方便地在Java程序中执行SQL语句,进行数据的读写操作。标题提及的是"mysql的jdbc...

    mysql-jdbc.jar

    MySQL JDBC驱动程序,通常...总之,`mysql-jdbc.jar`是Java开发者与MySQL数据库交互的核心工具,它简化了数据库操作,促进了跨平台的数据库应用开发。正确使用和理解这个驱动,对于任何Java开发者来说都是必备的技能。

    jdbc-批量插入数据

    首先,我们需要了解JDBC的批量操作接口。`java.sql.Statement`和`java.sql.PreparedStatement`接口都提供了批量处理的方法。批量处理主要通过`addBatch()`方法添加SQL语句到批处理队列,然后通过`executeBatch()`...

    C++操作MYSQL库类JDBC

    然而,C++没有内置的JDBC接口,所以这里提到的"C++操作MYSQL库类JDBC"可能是指用C++实现的一个类似JDBC的库,以便在C++程序中使用与JDBC相似的API来连接和操作MySQL数据库。 在C++中,通常我们会使用MySQL ...

    MySQL jdbc连接器 jdbc.zip

    例如,从5.x到8.x,MySQL引入了窗口函数、JSON数据类型、多线程复制等新特性,JDBC驱动随之进行了相应的支持。同时,连接器也不断进行性能提升,如减少网络通信、优化结果集处理等,以提高Java应用的数据库操作效率...

    Java实现批量向mysql写入数据的方法

    本文中提供了一个完整的示例代码,演示了Java实现批量向mysql写入数据的方法,包括JDBC连接mysql数据库、批量向mysql写入数据和基本的异常处理等操作。该示例代码可以作为Java程序设计的参考,帮助读者更好地理解...

    JSP+Servlet+JDBC实现MYSQL增删改查

    在本文中,我们将深入探讨如何使用JSP(JavaServer Pages)、Servlet和JDBC(Java Database Connectivity)来实现MySQL数据库的增、删、改、查操作。这种方法在小型项目中非常常见,但也有其局限性,如代码与SQL语句...

    jdbc连接mysql工具类

    MySQL是一款广泛应用的关系型数据库管理系统,它与JDBC结合,为开发者提供了方便的数据操作接口。下面将详细介绍如何使用Eclipse作为开发环境,通过编写一个JDBC工具类来连接MySQL数据库,并实现基本的增删改查功能...

    oracle mysql jdbc驱动

    Oracle MySQL JDBC驱动是连接Oracle数据库和Java应用程序的重要组件,它允许Java程序通过Java Database Connectivity (JDBC) API与MySQL数据库进行交互。Oracle公司为MySQL提供官方的JDBC驱动,确保了高效、稳定的...

    java开发mysql8的jdbc驱动包.rar

    JDBC驱动包的使用不仅限于简单的CRUD操作,还支持存储过程、批量操作、连接池管理等复杂功能。在实际开发中,了解JDBC的性能优化技巧,如批处理、预编译的语句、连接池配置等,也是至关重要的。 总之,Java开发...

    mysql-connector-java-5.1.35 MySQL的jdbc驱动jar

    MySQL的JDBC驱动,全称为Java Database Connectivity ...随着MySQL的版本更新,JDBC驱动也会随之升级,以支持新的数据库功能和改进的API。因此,对于新项目,建议使用最新稳定版的JDBC驱动,以获得最佳的兼容性和性能。

    JDBC连接Mysql数据库案例

    本案例将探讨如何使用JDBC连接MySQL数据库,并通过实际的代码示例讲解整个过程。我们将涉及以下知识点: 1. **JDBC驱动注册**: 在Java中,连接MySQL数据库首先需要加载并注册JDBC驱动。MySQL的JDBC驱动类是`...

    mysql,jdbc详解,与ibatis对比。批量查询,分页处理。

    ### MySQL、JDBC详解及与iBatis对比 ...通过对MySQL的基本操作、JDBC的工作原理以及iBatis与JDBC的对比分析,我们可以更全面地理解数据库编程的关键概念和技术要点。希望本文能够帮助开发者们更加熟练地掌握这些技能。

    spring jdbc Templatetest 访问mysql数据库,批量插入数据

    本主题将详细讲解如何使用Spring JDBC Template访问MySQL数据库并进行批量插入数据的操作。 首先,我们需要在项目中引入Spring框架的相关依赖,通常包括`spring-context`和`spring-jdbc`。这些可以在Maven或Gradle...

Global site tag (gtag.js) - Google Analytics