JDBC的批量批量插入

一. JDBC的批量插入

使用MySQL的Batch批量处理,
JDBC驱动版本需要5.1.13或以上
测试使用的JDBC驱动版本:mysql-connector-java-5.1.18-bin

(一开始我忽略掉这个jar包的条件要求了,使用的是mysql-connector-java-5.1.6-bin.jar在批处理插入时候效率和普通一样)

测试表结构如下:
CREATE TABLE test (
  id int(11) DEFAULT NULL,
  name varchar(20) DEFAULT NULL
) ENGINE=InnoDB 

 

首先使用普通的方式插入100万条数据,使用时间154901毫秒
程序如下:

复制代码
 1     public static void generalInsert() throws ClassNotFoundException,SQLException{
 2         long start = System.currentTimeMillis();
 3         Class.forName("com.mysql.jdbc.Driver");
 4         Connection connection = DriverManager.getConnection(
 5                 "jdbc:mysql://127.0.0.1:3306/kxh", "root", "root");
 6 
 7         connection.setAutoCommit(false);
 8         PreparedStatement cmd = connection
 9                 .prepareStatement("insert into test values(?,?)");
10 
11         for (int i = 0; i < 1000000; i++) {
12             cmd.setInt(1, i);
13             cmd.setString(2, "test");
14             cmd.executeUpdate();
15         }
16         connection.commit();
17 
18         cmd.close();
19         connection.close();
20 
21         long end = System.currentTimeMillis();
22         System.out.println(end - start);//158918毫秒
23     }
复制代码

使用批量处理100万条数据,仅用24675毫秒,提升效果非常明显,提升了6倍多.

程序如下:

复制代码
 1     public static void batchInsert() throws ClassNotFoundException, SQLException{
 2         long start = System.currentTimeMillis();
 3         Class.forName("com.mysql.jdbc.Driver");
 4         Connection connection = DriverManager.getConnection(
 5                         "jdbc:mysql://127.0.0.1:3306/kxh?useServerPrepStmts=false&rewriteBatchedStatements=true",
 6                         "root", "root");
 7 
 8         connection.setAutoCommit(false);
 9         PreparedStatement cmd = connection
10                 .prepareStatement("insert into test1 values(?,?)");
11         
12         for (int i = 0; i < 1000000; i++) {//100万条数据
13             cmd.setInt(1, i);
14             cmd.setString(2, "test");
15             cmd.addBatch();
16             if(i%1000==0){
17                 cmd.executeBatch();
18             }
19         }
20         cmd.executeBatch();
21         connection.commit();
22         
23         cmd.close();
24         connection.close();
25         
26         long end = System.currentTimeMillis();27         System.out.println("批量插入需要时间:"+(end - start)); //批量插入需要时间:24675
28     }
复制代码

 

MySQL Jdbc驱动在默认情况下会无视executeBatch()语句,把我们期望批量执行的一组sql语句拆散,一条一条地发给MySQL数据库,直接造成较低的性能。

与Oracle不同的是,Mysql需要添加rewriteBatchedStatements=true的参数,才可以使用批量处理,否则还是使用逐条处理的方式。

另外,有人说rewriteBatchedStatements只对INSERT有效,有人说它对UPDATE/DELETE也有效。通过试验结论是: 这个选项对INSERT/UPDATE/DELETE都有效,只不过对INSERT它为会预先重排一下SQL语句


开启MySQL的查询日志general_log(关于如何打开,查看mysql的日志请查看博客:http://www.cnblogs.com/DreamDrive/p/5761005.html),发现如下SQL
INSERT INTO test  VALUES (11, 'test'), (12, 'test'), (13, 'test')......


上下两行的id号码正好相差1000,也就是代码中设置的每1000次提交一次批处理.

如果使用普通的插入打印日志如下:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值