MySql的对比下,两者有数量级的差距。

表ddl:

CREATE TABLE tb04
(
"ID" ,) not null primary key,
"NAME" NVARCHAR2() not null,
"AGE" ,)  not null ,
"CREATEDTIME" ) not null
)

代码如下:

package com.hy;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 数据库连接参数
 * @author horn1
 *
 */
class DbParam{
    final String Driver = "oracle.jdbc.driver.OracleDriver";
    final String DbUrl = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
    final String User = "ufo";
    final String Pswd = "1234";
}

class TypeField{
    String type;
    String field;
}
/**
 *      多表批量插入器
 * @author horn1
 *
 */
public class MultiTbBatchInserter {
    private final int BatchSize=150;// 经有限测试,150已经趋近本机最值

    // 有三个表需要插入,如果是多个表,扩充数组即可
    // PK:主键 CH:文字 DT:Datetime,还可以根据需要扩充代号,在getInsertSql函数中则根据代号来设置值
    private final String[][] tableArray= {
            {"tb04:10000000","PK:ID","CH:NAME","CH:AGE","DT:CREATEDTIME"},
            //{"tb02:1000000","PK:ID","CH:SN","CH:NAME","CH:AGE","DT:CREATEDTIME"},
            //{"tb03:1000000","PK:ID","CH:SN","CH:NAME","CH:AGE","CH:Address","DT:CREATEDTIME"},
            };

    /**
     * 批量插值
     */
    public void batchInsert() {
        DbParam dbParam=new DbParam();
        Connection conn = null;
        Statement stmt = null;

        try{
            Class.forName(dbParam.Driver).newInstance();
            conn = DriverManager.getConnection(dbParam.DbUrl, dbParam.User, dbParam.Pswd);
            stmt = conn.createStatement();
            System.out.println("Begin to access "+dbParam.DbUrl+" as "+dbParam.User+"...");

            for(String[] innerArr:tableArray) {
                String tableName=innerArr[0].split(":")[0];
                int count=Integer.parseInt(innerArr[0].split(":")[1]);
                System.out.println("准备向表"+tableName+"插入"+count+"条记录.");

                // 插值前先清空
                truncateTable(tableName,conn,stmt);

                // 真正插入数据
                insertTestDataTo(tableName,count,innerArr,conn,stmt);
            }
        } catch (Exception e) {
            System.out.print(e.getMessage());
        } finally {
            try {
                stmt.close();
                conn.close();
            } catch (SQLException e) {
                System.out.print("Can't close stmt/conn because of " + e.getMessage());
            }
        }
    }

    /**
     * 以当前时间为基准减去数十秒
     * @param n
     * @return
     */
    private static String getDatetimeBefore(int n) {
        try {
            Calendar now = Calendar.getInstance();
            now.add(Calendar.SECOND,-n*10);//日期减去n*10秒

            Date newDate=now.getTime();

            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String retval = sdf.format(newDate);
            return retval;
        }
        catch(Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * 清空一个表的数据,注意此功能有破坏性,不可恢复,注意备份好数据
     * @param tableName
     * @param conn
     * @param stmt
     * @throws SQLException
     */
    private void truncateTable(String tableName,Connection conn,Statement stmt) throws SQLException{
        String sql="truncate table "+tableName;
        stmt.execute(sql);
        System.out.println("truncated table:"+tableName);
    }

    /**
     * 向一个表插入数据
     * @param tableName
     * @param count
     * @param innerArr
     * @param conn
     * @param stmt
     * @throws SQLException
     */
    private void insertTestDataTo(String tableName,int count,String[] innerArr,Connection conn,Statement stmt) throws SQLException{
        // 得到字段名和字段类型
        List<TypeField> typefields=new ArrayList<TypeField>();
        for(int i=1;i<innerArr.length;i++) {
            String temp=innerArr[i];
            String[] arrTmp=temp.split(":");

            TypeField tf=new TypeField();
            tf.type=arrTmp[0];
            tf.field=arrTmp[1];
            typefields.add(tf);
        }

        List<String> fields=new ArrayList<String>();
        List<String> values=new ArrayList<String>();
        int index=0;
        for(TypeField tf:typefields) {
            fields.add(tf.field);
            values.add("''{"+index+"}''");
            index++;
        }

        index=0;
        int times=count/BatchSize;
        for(int i=0;i<times;i++) {
            StringBuilder sb=new StringBuilder();
            sb.append("INSERT ALL ");

            for(int j=0;j<BatchSize;j++) {
                index=i*BatchSize+j;
                sb.append(getInsertSql(tableName,typefields,index));
            }

            sb.append(" select * from dual");
            String sql = sb.toString();
            //System.out.println("sql="+sql);
            stmt.executeUpdate(sql);
            System.out.println("#"+i+" "+BatchSize+" records inserted to "+tableName);
        }
    }

    /**
     * 得到批量插入语句
     * @param tableName
     * @param typefields
     * @param index
     * @return
     */
    private String getInsertSql(String tableName,List<TypeField> typefields,int index) {
        String currTime=getDatetimeBefore(index);

        StringBuilder sb=new StringBuilder();
        sb.append(" 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")) {
                values.add("'"+String.valueOf(index)+"'");
            }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')");
            }
        }
        sb.append(String.join(",",values));
        sb.append(")");

        String insertSql=sb.toString();
        return insertSql;
    }

    /**
     * 将秒转化为日时分秒
     * @param secondCount
     * @return
     */
    private static String sec2DHMS(long secondCount) {
        String retval = null;

        long days = secondCount / (60 * 60 * 24);
        long hours = (secondCount % (60 * 60 * 24)) / (60 * 60);
        long minutes = (secondCount % (60 * 60)) / 60;
        long seconds = secondCount % 60;

        String strSeconds="";
        if(seconds!=0) {
            strSeconds=seconds + "s";
        }

        if (days > 0) {
            retval = days + "d" + hours + "h" + minutes + "m" + strSeconds;
        } else if (hours > 0) {
            retval = hours + "h" + minutes + "m" + strSeconds;
        } else if (minutes > 0) {
            retval = minutes + "m" + strSeconds;
        } else {
            retval = strSeconds;
        }

        return retval;
    }

    public static void main(String[] args) {
        MultiTbBatchInserter mi=new MultiTbBatchInserter();
        long startTime = System.currentTimeMillis();
        mi.batchInsert();
        long endTime = System.currentTimeMillis();

        System.out.println("Time elapsed:" + sec2DHMS((endTime - startTime)/1000) );
    }
}

输出:

#66658 150 records inserted to tb04
#66659 150 records inserted to tb04
#66660 150 records inserted to tb04
#66661 150 records inserted to tb04
#66662 150 records inserted to tb04
#66663 150 records inserted to tb04
#66664 150 records inserted to tb04
#66665 150 records inserted to tb04
Time elapsed:1h2m15s

数据库记录:

--END-- 2019年11月9日19:19:33

【Oracle】往Oracle11g的某表插入近千万条记录,耗时略超一小时的更多相关文章

  1. oracle通过sql随机取表中的10条记录

    oracle通过sql随机取表中的10条记录: SELECT * FROM (SELECT * FROM T_USER ORDER BY DBMS_RANDOM.RANDOM()) WHERE Row ...

  2. [MyBatis]再次向MySql一张表插入一千万条数据 批量插入 用时5m24s

    本例代码下载:https://files.cnblogs.com/files/xiandedanteng/InsertMillionComparison20191012.rar 环境依然和原来一样. ...

  3. 【java】[sql]使用Java程序向MySql数据库插入一千万条记录,各种方式的比较,最后发现insert批量插入方式对效率提升最明显

    我的数据库环境是mysql Ver 14.14 Distrib 5.6.45, for Linux (x86_64) using EditLine wrapper 这个数据库是安装在T440p的虚拟机 ...

  4. MSSQL SELECT(刚刚)新插入到表中的那条记录

    假设对表 TXxxxxxxx 表新插入一条记录,然后要 SELECT 出刚刚插入的这条记录.可使用 SCOPE_IDENEITY(); 处理.具体代码参考如下: INSERT INTO TXxxxxx ...

  5. [MyBatis]五分钟向MySql数据库插入一千万条数据 批量插入 用时5分左右

    本例代码下载:https://files.cnblogs.com/files/xiandedanteng/InsertMillionComparison20191012.rar 我的数据库环境是mys ...

  6. 关于Delphi cxGrid主从表中从表只能编辑第一条记录的问题

    在Delphi cxGrid主从表中从表只能编辑第一条记录,这个问题是由于设置主从关联字段错误造成的. 从表DBtableView2的keyfieldnames,DetailKeyFieldNames ...

  7. 如何在十分钟内插入1亿条记录到Oracle数据库?

    这里提供一种方法,使用 APPEND 提示,使得十分钟内插入上亿数据成为可能. -- Create table create table TMP_TEST_CHAS_LEE ( f01 VARCHAR ...

  8. Oracle数据库delete删除普通堆表千万条记录

    Oracle数据库delete删除普通堆表千万条历史记录. 直接删除的影响: 1.可能由于undo表空间不足从而导致最终删除失败的问题: 2.可能导致undo表空间过度使用,影响到其他用户正常操作. ...

  9. Oracle查询出最最近一次的一条记录

    需求:从一个表中查询数据,得到的数据为最新的一条记录. -------------建立测试表 --drop table TB ),dtDate date) -------------插入测试数据 ,' ...

随机推荐

  1. Yarn介绍(设计理念与基本架构)

    Yarn : 新的计算框架,是一个全局资源管理器,负责整个集群的资源管理和分配   一. Yarn产生背景       Hadoop1.0MR有局限性,概括为以下几个方面 :  扩展性差 可靠性差 资 ...

  2. Python函数Day2

    一.函数补充 只有一个参数时,变量用argv 二.动态参数 为了拓展,对于传入的实参数量不固定,需要万能参数,即动态参数 *args **kwargs 在函数定义时,在 *args为位置参数,起聚合的 ...

  3. Python memory error的问题

    前段时间在读取一个文件的过程中,竟然出现了Memory Error!简直让我怀疑自己买了个假电脑,毕竟是8G内存i7处理器,一度怀疑自己装了假的内存条....下面说一下几个解题步骤....一般就是用下 ...

  4. PHP危险函数的持续学习

    记录下遇到过的PHP危险函数 0x01 escapeshellarg()与escapeshellsmd()联合 先给出官方的定义: escapeshellarg ( string $arg ) : s ...

  5. .NET Core 调试出现“应用程序处于中断模式”

    今天再看博客园的大神博客,按照例子写了一个文件读写的示例(对 .NET Core FileProvider 的应用). 在调试的时候出现了“应用程序处于中断模式”的问题,继续的话程序并没有向下执行,看 ...

  6. Django中的日期和时间格式 DateTimeField

    创建django的model时,有DateTimeField.DateField和TimeField三种类型可以用来创建日期字段,其值分别对应着datetime().date().time()三中对象 ...

  7. 包,logging日志模块,copy深浅拷贝

    一 包 package 包就是一个包含了 __init__.py文件的文件夹 包是模块的一种表现形式,包即模块 首次导入包: 先创建一个执行文件的名称空间 1.创建包下面的__init__.py文件的 ...

  8. BZOJ 3698: XWW的难题(有源汇上下界最大流)

    题面 XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核. XWW给你出了这么一个难题:XWW给你一个N*N的正实数矩阵A, ...

  9. Luogu 4751 动态DP 模板

    题面 动态求最大独立集 题解 树剖后用矩阵转移. 具体见Tweetuzki的洛谷博客 CODE #include <bits/stdc++.h> using namespace std; ...

  10. element案例大杂烩

    修改表头字体粗细? <el-table :data="list" header-row-class-name="tableHead"> 自定义即可 ...