// Initialize conn&stmt
Connection conn=null;
Statement stmt=null;

...

conn=dataSource.getConnection();
stmt = conn.createStatement();

...

conn.setAutoCommit(false);
stmt = conn.createStatement();

for(int i=0;i<recordCount;i++) {
    String insertSql=getInsertSql(tableName,typefields,currTime,i);
    stmt.addBatch(insertSql);
    currTime=timePastNSecond(currTime,nSeconds);

    if( (i!=0) && (i % 1000==0) ) { // 这里控制壹千条插入语句一提交
        stmt.executeBatch();
        stmt.clearBatch();
        conn.commit();
        logger.info("."+index+" 1000 records have been inserted to table:'"+tableName+"'.");
    }
}

// 最后再提交一次
stmt.executeBatch();
stmt.clearBatch();
conn.commit();

这个方法试下来,在我遇到的Oracle(Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production )上, 插入638万条数据(两张大表一个三百万,其余19张小表每张两万)花费9小时多,而之前的插入语句(一条insert一提交)插入419万条数据(两张大表一个二百万,其余19张小表每张一万)花费6个半小时,感觉提升并不明显。当然,我得到的sql语句因为表不一样造成Insert语句不一致,可能也是效率提升不明显的原因。

我的原有方案是这样写的:

conn.setAutoCommit(false);

for(int i=0;i<recordCount;i++) {
    StringBuilder sb=new StringBuilder();
    sb.append("insert into "+tableName+"(");
    List<String> fields=new ArrayList<String>();
    for(TypeField tf:typefields) {
        fields.add(tf.field);
    }
    sb.append(String.join(",",fields));

    sb.append(") values(");
    List<String> values=new ArrayList<String>();
    for(TypeField tf:typefields) {
        if(tf.type.equals("PK")) {
            if(tableName.equals("DELIVERY_INFO_HISTORY")) {
                values.add("'0'");
            }else {
                values.add("'"+String.valueOf(i)+"'");
            }
        }else if(tf.type.equals("CH")) {
            values.add("'0'");
        }else if(tf.type.equals("DT")) {
            values.add("to_date('"+currTime+"','yyyy-MM-dd HH24:mi:ss')");
        }else if(tf.type.equals("US")) {
            values.add("'UserABC'");
        }
    }
    sb.append(String.join(",",values));
    sb.append(")");

    String insertSql=sb.toString();

    insertedActual+=stmt.executeUpdate(insertSql); 

    currTime=timePastNSecond(currTime,nSeconds);

    if( recordCount>0 && recordCount % 1000==0 ) {
        conn.commit();
    }
}

conn.commit();
logger.info("#"+index+" "+insertedActual+" records(expected:"+recordCount+") have been inserted to table:'"+tableName+"'.");

只是纯Insert语句插入提交,没想速度居然差不多。真应了那句话,纸上得来终觉浅,绝知此事要躬行。

参考资料:

1. https://www.cnblogs.com/myseries/p/11191134.html

2.https://www.cnblogs.com/shizhijie/p/7458813.html

--END-- 2019-10-10 8:15

[JDBC]批量提交插入语句以提高数据插入速度(效率提升不明显)的更多相关文章

  1. jdbc 01: 连接mysql,并实现数据插入

    jdbc连接mysql,并实现数据插入 package com.examples.jdbc.o1_连接与插入; import java.sql.*; /* jdbc数据库连接六步 */ public ...

  2. php中bindValue的批量提交sql语句

    php预编译sql语句,可以批量提交sql,也可以实现防注入 <?php $dsn='mysql:host=127.0.0.1;port=3306;dbname=bisai'; $usernam ...

  3. 将Sql查询语句获取的数据插入到List列表里面

    Sql查询语句获取的数据是分格式的,我们还用SqlDataReader来做,然后用IDataReader来接收读取,以下是代码: //我想查询一个用户表的信息,该用户有姓名,密码,信息三列 //1.定 ...

  4. PostgresSQL使用Copy命令能大大提高数据导入速度

    最近在做会员系统,其中会员系统有一份企业信息初始化的数据,需要从SQL Server数据库导入到PostgreSQL,单表的数据近30万.最开始的方案是在SQL Server上生成insert int ...

  5. Javascript高性能编程-提高数据访问速度

         hasOwnProperty()仅检索实例不检索原型,in即检索实例,又检索原型      成员嵌套越深,访问速度越慢,只在必要的情况下使用对象成员.      如果在同一个函数中你要多次读 ...

  6. 执行插入语句时直接返回插入信息的自增id,判断是否为空

    insert into userinfo(UserName,UserPass,RegTime,email)values('a','b',GETDATE(),'123@qq.com');select @ ...

  7. 将EXCEL中的列拼接成SQL insert插入语句

    工作中经常需要将EXCEL文件中的数据导入到各种数据库,但是对于不熟悉数据库的人来说,如果直接使用命令执行导入,这无疑是一个难题,也是一个风险.这里我们直接在EXCEL文件中拼接成标准的SQL ins ...

  8. 解决 C++ 操作 MySQL 大量数据插入效率低下问题

    往 Mysql 中,插入10000条简单数据.速度很缓慢,竟然要5分钟左右, 可是打开事务的话.一秒不到就搞定了 代码: #include <iostream> #include < ...

  9. MySQL:JDBC批量插入数据的效率

    平时使用mysql插入.查询数据都没有注意过效率,今天在for循环中使用JDBC插入1000条数据居然等待了一会儿 就来探索一下JDBC的批量插入语句对效率的提高 首先进行建表 create tabl ...

随机推荐

  1. SpringCloud之Feign声明式调用原理及配置

    1 什么是Feign Feign是一种声明式.模板化的HTTP客户端(仅在Application Client中使用).声明式调用是指,就像调用本地方法一样调用远程方法,无需感知操作远程http请求. ...

  2. JPA中的复杂查询

    JPQL全称Java Persistence Query Language 基于首次在EJB2.0中引入的EJB查询语言(EJB QL),Java持久化查询语言(JPQL)是一种可移植的查询语言,旨在 ...

  3. Mybatis入门配置及第一个Mybatis程序

    目的:使用mybatis来进行对数据库表的操作 第一步:引入jar包 我这里是创建的maven工程 第二步:创建数据表user 第三步:创建实体类 实体类放在包 com.xxx.pojo 下,包名可自 ...

  4. PAT Advanced 1155 Heap Paths (30 分)

    In computer science, a heap is a specialized tree-based data structure that satisfies the heap prope ...

  5. springMVC的简单了解和环境搭建

    一,什么mvc 模型-视图-控制器(MVC)是一个众所周知的以设计界面应用程序为基础的设计思想.它主要通过 分离模型.视图及控制器在应用程序中的角色 将业务逻辑从界面中解耦.通常, 模型负责封装应用程 ...

  6. Linux的.a、.so和.o文件及链接时的命名

    在说明Linux的.a..so和.o文件关系之前,先来看看windows下obj,lib,dll,exe的关系 windows下obj,lib,dll,exe的关系 lib是和dll对应的.lib是静 ...

  7. Java8-Stream-No.11

    import java.util.Arrays; import java.util.List; public class Streams11 { static class Person { Strin ...

  8. BZOJ 4260: Codechef REBXOR (trie树维护异或最大值)

    题意 分析 将区间异或和转化为前缀异或和.那么[L,R][L,R][L,R]的异或和就等于presum[R] xor presum[L−1]presum[R]\ xor \ presum[L-1]pr ...

  9. 【leetcode】1288. Remove Covered Intervals

    题目如下: Given a list of intervals, remove all intervals that are covered by another interval in the li ...

  10. vue项目实现详情页后退缓存之前的数据

    vue项目实现详情页后退缓存之前的数据 2019年02月19日 14:54:57 不想写代码的程序员 阅读数:244   一.需要缓存的内容: 1.后退缓存条件查询的数据 2.后退缓存分页信息 二.实 ...