【Oracle/Java】向三张表各插入百万数据,共用时18分3秒,平均每张表6分钟
三张表DDL如下:
CREATE TABLE tb01 ( "ID" ,) not null primary key, "NAME" NVARCHAR2() not null, "AGE" ,) not null , "CREATEDTIME" ) not null ) CREATE TABLE tb02 ( "ID" ,) not null primary key, "SN" NVARCHAR2() not null, "NAME" NVARCHAR2() not null, "AGE" ,) not null , "CREATEDTIME" ) not null ) CREATE TABLE tb03 ( "ID" ,) not null primary key, "SN" NVARCHAR2() not null, "NAME" NVARCHAR2() not null, "AGE" ,) not null , "ADDRESS" NVARCHAR2() 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=100; // 有三个表需要插入,如果是多个表,扩充数组即可 // PK:主键 CH:文字 DT:Datetime,还可以根据需要扩充代号,在getInsertSql函数中则根据代号来设置值 private final String[][] tableArray= { {"tb01:1000000","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"); } } /** * 得到批量插入语句 * @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) ); } }
输出:
#9990 100 records inserted #9991 100 records inserted #9992 100 records inserted #9993 100 records inserted #9994 100 records inserted #9995 100 records inserted #9996 100 records inserted #9997 100 records inserted #9998 100 records inserted #9999 100 records inserted Time elapsed:18m3s
数据库的情况:
主程序稍微扩充一下就是一款性能测试的利器。
--END-- 2019年11月9日15:38:35
【Oracle/Java】向三张表各插入百万数据,共用时18分3秒,平均每张表6分钟的更多相关文章
- 【java/oralce/sql】往一张仅有id,名称,创建时间三个字段的表中插入百万数据需要多久?1分26秒
代码下载:https://files.cnblogs.com/files/xiandedanteng/fastfilltable20191222.rar 表testtb18的结构如下: CREATE ...
- 在mysql数据库中创建oracle scott用户的四个表及插入初始化数据
在mysql数据库中创建oracle scott用户的四个表及插入初始化数据 /* 功能:创建 scott 数据库中的 dept 表 */ create table dept( deptno int ...
- MySQL_(Java)使用JDBC向数据库中插入(insert)数据
MySQL_(Java)使用JDBC向数据库发起查询请求 传送门 MySQL_(Java)使用JDBC向数据库中插入(insert)数据 传送门 MySQL_(Java)使用JDBC向数据库中删除(d ...
- 【Oracle/Java】以Insert ALL方式向表中插入百万条记录,耗时9分17秒
由于按一千条一插程序长期无反应,之后改为百条一插方式,运行完发现插入百万记录需要9m17s,虽然比MySQL效率差,但比单条插入已经好不少了. 对Oracle的批量插入语法不明的请参考:https:/ ...
- 快速向表中插入大量数据Oracle中append与Nologging
来源于:http://blog.sina.com.cn/s/blog_61cd89f60102e7gi.html 当需要对一个非常大的表INSERT的时候,会消耗非常多的资源,因为update表的时候 ...
- JDBC插入百万数据,不到5秒!
java自带的批量操作,就可以很好的支持大量数据的处理.相比c#,简单很多.c#要使用oracle提供的ODP.NET,效率才很高,但是代码却很复杂.总之,在这方面,c#没得比.当然,这里的表是没加索 ...
- php操作mysql,1分钟内插入百万数据
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/qq_33862644/article/d ...
- JAVA中计算两个时间相差多少 天,时,分,秒
1: import java.util.Date; 2: 3: public class ShowTimeInterval{ 4: public void ShowTimeInterval(Date ...
- Oracle 生成一张测试表并插入随机数据
--生成随机表 --CREATE table scott.One_Million as ( SELECT ROWNUM AS T_ID, TRUNC(DBMS_RANDOM.VALUE(, )) 年龄 ...
随机推荐
- 【SpringMVC】请求乱码处理
一.post请求乱码 二.get请求乱码 一.post请求乱码 在web.xml中加入 <filter> <filter-name>CharacterEncodingFilte ...
- Linux 磁盘、分区、文件系统、挂载
磁盘 Linux所有设备都被抽象成为一个文件,保存在/dev目录下. 设备名称一般为hd[a-z]或sd[a-z].如果电脑中有多硬盘,则设备名依次为sda.adb.sdc...以此类推 IDE设备的 ...
- Scyther Advanced Topics
建立非对称秘钥对 声明一个公钥函数和一个私钥函数: const pk2: Function ; const sk2: Function : 我们还声明这些函数代表非对称密钥对: inversekeys ...
- 剖析.o文件ELF组成
ELF文件结构组成 ①总共13个节 ②每个节都有一个编号.从ELF头开始编号,编号从0开始,编号的作用就是用来索引(找到)不同节的. ③每个.o的都是这样的结构.链接时要做的就是,将ELF格式的.o全 ...
- MyBatis3_[tp_38~]_动态sql_if_判断&OGNL_where标签_
笔记要点出错分析与总结 /** 笔记: * 查询的时候,如果某些条件,没带可能SQL拼装会有问题; * 1.-->给where 后面加上 1=1, 以后的条件都and XXX * 2. < ...
- 全球化 System.Globalization.CultureInfo与RegionInfo类
一.CultureInfo类:文化信息 分类: 1.中立文化(Neutral culture): zh-CHS:中文,无区域信息,无格式化信息 2.特定区域文化(Specific culture) z ...
- Java原子类--AtomicLongFieldUpdater
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3514623.html AtomicLongFieldUpdater介绍和函数列表 AtomicLongF ...
- BZOJ4802 欧拉函数 (Pollard-Rho Miller-Robin)
题目 求大数的欧拉函数φ\varphiφ 题解 Pollard-Rho 板子 CODE #pragma GCC optimize (3) #include <bits/stdc++.h> ...
- .netcore 打包发布到ubuntu linux上
使用命令行发布如下 cd NetCoreServerOne // project file place 项目文件 所在目录 dotnet build -r ubuntu.16.04-x6 ...
- php MySQL 删除数据表
MySQL 删除数据表 MySQL中删除数据表是非常容易操作的, 但是你再进行删除表操作时要非常小心,因为执行删除命令后所有数据都会消失. 语法 以下为删除MySQL数据表的通用语法: DROP TA ...