使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(10W+),如何提高效率呢?

在JDBC编程接口中Statement 有两个方法特别值得注意:

void addBatch() throws SQLException
Adds a set of parameters to this PreparedStatement object's batch of commands.
int[] executeBatch() throws SQLException
Submits a batch of commands to the database for execution and if all commands execute successfully, returns an array of update counts. The int elements of the array that is returned are ordered to correspond to the commands in the batch, which are ordered according to the order in which they were added to the batch. 
 
通过使用addBatch()和executeBatch()这一对方法可以实现批量处理数据。
 
不过值得注意的是,首先需要在数据库链接中设置手动提交,connection.setAutoCommit(false),然后在执行Statement之后执行connection.commit()。
  1. package cyl.demo.ipsearcher;
  2. import java.io.BufferedReader;
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import java.io.InputStreamReader;
  6. import java.sql.Connection;
  7. import java.sql.DriverManager;
  8. import java.sql.PreparedStatement;
  9. import java.sql.SQLException;
  10. public class DbStoreHelper {
  11. private String insert_sql;
  12. private String charset;
  13. private boolean debug;
  14. private String connectStr;
  15. private String username;
  16. private String password;
  17. public DbStoreHelper() {
  18. connectStr = "jdbc:mysql://localhost:3306/db_ip";
  19. // connectStr += "?useServerPrepStmts=false&rewriteBatchedStatements=true";
  20. insert_sql = "INSERT INTO tb_ipinfos (iplong1,iplong2,ipstr1,ipstr2,ipdesc) VALUES (?,?,?,?,?)";
  21. charset = "gbk";
  22. debug = true;
  23. username = "root";
  24. password = "***";
  25. }
  26. public void storeToDb(String srcFile) throws IOException {
  27. BufferedReader bfr = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile), charset));
  28. try {
  29. doStore(bfr);
  30. } catch (Exception e) {
  31. e.printStackTrace();
  32. } finally {
  33. bfr.close();
  34. }
  35. }
  36. private void doStore(BufferedReader bfr) throws ClassNotFoundException, SQLException, IOException {
  37. Class.forName("com.mysql.jdbc.Driver");
  38. Connection conn = DriverManager.getConnection(connectStr, username,password);
  39. conn.setAutoCommit(false); // 设置手动提交
  40. int count = 0;
  41. PreparedStatement psts = conn.prepareStatement(insert_sql);
  42. String line = null;
  43. while (null != (line = bfr.readLine())) {
  44. String[] infos = line.split(";");
  45. if (infos.length < 5)   continue;
  46. if (debug) {
  47. System.out.println(line);
  48. }
  49. psts.setLong(1, Long.valueOf(infos[0]));
  50. psts.setLong(2, Long.valueOf(infos[1]));
  51. psts.setString(3, infos[2]);
  52. psts.setString(4, infos[3]);
  53. psts.setString(5, infos[4]);
  54. psts.addBatch();          // 加入批量处理
  55. count++;
  56. }
  57. psts.executeBatch(); // 执行批量处理
  58. conn.commit();  // 提交
  59. System.out.println("All down : " + count);
  60. conn.close();
  61. }
  62. }
执行完成以后:
  1. All down : 103498
  2. Convert finished.
  3. All spend time/s : 47

一共10W+,执行时间一共花费 47 秒.

 
这个效率仍然不高,似乎没有达到想要的效果,需要进一步改进。
在MySQL JDBC连接字符串中还可以加入参数,
rewriteBatchedStatements=true,mysql默认关闭了batch处理,通过此参数进行打开,这个参数可以重写向数据库提交的SQL语句,具体参见:http://www.cnblogs.com/chenjianjx/archive/2012/08/14/2637914.html
useServerPrepStmts=false,如果不开启(useServerPrepStmts=false),使用com.mysql.jdbc.PreparedStatement进行本地SQL拼装,最后送到db上就是已经替换了?后的最终SQL.
 
在此稍加改进,连接字符串中加入下面语句(代码构造方法中去掉注释):
connectStr += "?useServerPrepStmts=false&rewriteBatchedStatements=true";
 
再次执行如下:
  1. All down : 103498
  2. Convert finished.
  3. All spend time/s : 10
同样的数据量,这次执行只花费了10秒 ,处理效率大大提高.

使用JDBC在MySQL数据库中快速批量插入数据的更多相关文章

  1. 在 SQL 中 快速 批量 插入数据的方法

    方法1:逐条执行,速度慢. INSERT INTO testimport (name, message) VALUES ('testname', 'jfksdfkdsfjksadljfkdsfjsdl ...

  2. 使用jdbc将mysql数据库中的内容封装为指定对象的list集合

    使用jdbc将mysql数据库中的内容封装为指定对象的list集合 public List<User> findAll() { private JdbcTemplate template ...

  3. net core天马行空系列-各大数据库快速批量插入数据方法汇总

    1.前言 hi,大家好,我是三合.我是怎么想起写一篇关于数据库快速批量插入的博客的呢?事情起源于我们工作中的一个需求,简单来说,就是有一个定时任务,从数据库里获取大量数据,在应用层面经过处理后再把结果 ...

  4. Java—JDBC向mysql数据库中给某个表添加数据时,会遇到的问题,如下

    解析(jar包该放在那里,以及其它的操作): 把jar包(驱动)添加到自己的项目中,最好新建一个文件夹,再把jar包(驱动包)添加到这个所新建的文件中 1.先建好自己的项目,再新建一个文件夹,如下: ...

  5. 通过java代码往mysql数据库中写入日期相关数据少13个小时

    通过show variables like '%time_zone%'; 查看时区: CST 时区 名为 CST 的时区是一个很混乱的时区,有四种含义: 美国中部时间 Central Standard ...

  6. 如何在MySQl数据库中给已有的数据表添加自增ID?

    由于使用MySQL数据库还没有多久的缘故,在搭建后台往数据库导入数据的时候发现新增的表单是没有自增id的,因次就有了上面这个问题. 解决方法 1.给某一张表先增加一个字段,这里我们就以node_tab ...

  7. ThinPHP3.2中 addAll()批量插入数据

    thinkphp中model类的addAll()方法可以将数据同时添加到数据库中. 1 2 3 4 5 6 // 批量添加数据 (only MySQL) $user = M('user'); //ar ...

  8. MySQL随机字符串函数批量插入数据

      简单举个例子: drop table if exists demo1 create table demo1 ( id int primary key auto_increment, name ) ...

  9. MariaDB快速批量插入数据的几种办法

    前言 当要向MariaDB中插入新的数据时,以下过程会影响插入所消耗的时间:(按时间消耗长短降序排序) 将数据sync到磁盘上(它是事务结束的一部分) 添加新的键值.索引越大,更新键值所消耗的时间就越 ...

随机推荐

  1. 步步为营-70-asp.net简单练习(文件的上传和下载)

    大文件的上传一般通过FTP协议,而一般小的文件可以通过http协议来完成 1 通过asp.net 完成图片的上传 1.1 创建html页面 注意:1 method="post" ; ...

  2. python自动抢票

    # -*- coding: utf-8 -*- from splinter.browser import Browser from time import sleep import traceback ...

  3. layer弹框插件使用

    需要在jquery之后导入 <link rel="stylesheet" href="${pageContext.request.contextPath }/js/ ...

  4. Mahout介绍和简单应用

    Mahout学习(主要学习内容是Mahout中推荐部分的ItemCF.UserCF.Hadoop集群部署运行) 1.Mahout是什么? Mahout是一个算法库,集成了很多算法. Apache Ma ...

  5. 024 SpringMvc的异常处理

    一:说明 1.介绍 Springmvc提供HandlerExceptionResolver处理异常,包括Handler映射,数据绑定,以及目标方法执行. 2.几个接口的实现类 AnnotationMe ...

  6. 内置函数 filter zip map

    1. 基本内置函数: 2. enumerate :  枚举 把列表转化为有索引的字典: 3. eval 和 exec 4. 过滤函数  filter 5. map 函数批量修改: 6. 配对函数 zi ...

  7. Sea Battle CodeForces - 729D

    题意: 有n个格子,a条船,每条船占b个格子.事先已经射击了k个格子,且这k次射击不会射到船上,求再射击几次可以射到某一条船的某一部分 思路: 观察样例可以发现,如果五个0,船的长度是3,那么这五个0 ...

  8. HTTP协议学习笔记(四)

    HTTP协议学习笔记(四) 与 HTTP 协作的 Web 服务器 一台 Web 服务器可搭建多个独立域名的 Web 网站,也可作为通信路径上的中转服务器提升传输效率. 1.用单台虚拟主机实现多个域名 ...

  9. P3420 [POI2005]SKA-Piggy Banks

    P3420 [POI2005]SKA-Piggy Banks套路题,a通过某种关系和其他的点建立关系.这种题不是环(dfs就可以了),就是并查集找连通块.这种题要建图,画图,就很清楚了. #inclu ...

  10. 进程描述和控制(os 笔记二)

    进程描述和控制 ​ 计算机最初的主要任务之一就是高效的自动化我们的工作,完成用户交付的任务.而这种任务在计算机中的表示就是一个个的进程.从上一篇文章中描述的计算机的发展历史我们能发现,无论是单道批处理 ...