博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
大数据量文件导入数据库
阅读量:6121 次
发布时间:2019-06-21

本文共 2915 字,大约阅读时间需要 9 分钟。

发现问题

最近项目中遇到需要导数据到远程数据库中,数据库服务器与应用程序服务器不在一台服务器上。 之前项目中使用insert all into table A(col1,col2) values (1,1) table A(col1,col2) values(2,2) select 1 from dual,导入600+M文件需要一个小时。 发现还有个3G的文件需要导入,算下来需要5-6小时。效率太差。

分析问题

  • 1、怀疑之前代码太复杂有问题,重新写insert all测试案例,发现效果一样,不行
  • 2、使用jdbc executeBatch方式,发现在分隔字符时报内存溢出OO了。 后续抽时间分析代码。
  • 3、使用sqlldr方式,不想自己手写脚本,发现这边文章不错.

测试

*1、测试100M文件

1)insert all与sqlldr导入100万数据,发现时间大致都是20分种2)去掉索引后,sqlldr导入100万数据3分钟就搞定。3)应用服务器与数据库服务器要隔离,那剩下的问题就是网络传输了(生产环境在同一个机房,千兆网,应该还可以接受)。复制代码

*2 测试3G文件

1)测试导入3G文件:使用sqlldr没有删除索引的时候,用了3.3个小时,   之前使用insert all需要5-6个小时,快了一半2)测试导入3G文件:使用sqlldr并删除索引,只用了30分钟,   bingo,就这个了。数据导入后再代码创建索引。复制代码

结论

  • 1、导入前先删除索引,导完再建索引(建索引可能也要时间)
  • 2、使用sqlldr方式导入

后续

  • 1、能不能设置数据库spool相关设置
  • 2、增加并行度测试:包括单个文件并行和多个文件并行
  • 3、可以使用从系统表中读取表结构、表字段的方式, 实现更灵活的生成CTL方式,实现更自动的导数方法

代码

package tset;import java.io.BufferedReader;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;public class testTimer {	/**	 * @param args	 */	public static void main(String[] args) {		// 写控制文件.ctl		long startTime=System.currentTimeMillis();		String fileRoute = "E:\\";// 文件地址路径				String fileName = "CRM_TRATION_EXP_S09_20181025.dat";// 数据文件名		String tableName = "tration_temp4ctl";// 表名		String fieldName = "C_TANO,C_CUSTNO,C_CUSTTYPE,C_AGENCYNO,C_FUNDACCO,C_TRADEACCO,C_NETNO,C_RATIONNO,F_BALANCE,C_RATIONTERM,L_DELAY,L_ALLOWFAIL,L_RATIONDATE,F_AGIO,C_RATIONSTATUS,C_FUNDCODE,C_SHARETYPE,L_TOTALTIMES,F_TOTALBALANCE,F_TOTALSHARES,D_FIRSTDATE,D_LASTDATE,D_PROTOCOLENDDATE,D_CLOSEDATE,L_SUCTIMES,L_MAXSUCTIMES,D_CDATE,D_OPENDATE,C_SARATIONNO";		String colAttr="VARCHAR2,VARCHAR2,CHAR,CHAR,VARCHAR2,VARCHAR2,VARCHAR2,VARCHAR2,NUMBER,VARCHAR2,NUMBER,NUMBER,NUMBER,NUMBER,VARCHAR2,VARCHAR2,CHAR,NUMBER,NUMBER,NUMBER,DATE,DATE,DATE,DATE,NUMBER,NUMBER,DATE,DATE,VARCHAR2";					String logfileName = tableName+".log";		String ctlfileName = tableName+".ctl";// 控制文件名		String cols=processCol(fieldName,colAttr);		stlFileWriter(fileRoute, fileName, tableName, cols, ctlfileName);		// 要执行的DOS命令		String user = "test";		String psw = "test";		String Database = "//10.50.101.101:1521/uat";// IP要指向数据库服务器的地址				Executive(user, psw, Database, fileRoute, ctlfileName, logfileName);				long costTime=System.currentTimeMillis()-startTime;		System.out.println(tableName+"内存:"+(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory())/1024L+"kb");		System.out.println(tableName+"内存:"+(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory())/1024L/1024L+"Mb");		System.out.println(tableName+"时间:"+costTime/1000f+"秒");		System.out.println(tableName+"时间:"+costTime/1000/60/60f+"小时");	}		private static String processCol(String fieldName,String colAttr){		String[] fields=fieldName.split(",");		String[] attrs=colAttr.split(",");				StringBuffer sb = new StringBuffer("(");		for (int i=0;i

才开始写博客,记录自己的一步一行

转载于:https://juejin.im/post/5bee1465f265da611f074599

你可能感兴趣的文章
mysql-python模块编译问题解决
查看>>
Oracle中drop user和drop user cascade的区别
查看>>
【Linux】linux经常使用基本命令
查看>>
Java 内存区域和GC机制
查看>>
更新代码和工具,组织起来,提供所有博文(C++,2014.09)
查看>>
HTML模块化:使用HTML5 Boilerplate模板
查看>>
登记申请汇总
查看>>
Google最新截屏案例详解
查看>>
2015第31周一
查看>>
2015第31周日
查看>>
在使用EF开发时候,遇到 using 语句中使用的类型必须可隐式转换为“System.IDisposable“ 这个问题。...
查看>>
Oracle 如何提交手册Cluster Table事务
查看>>
BeagleBone Black第八课板:建立Eclipse编程环境
查看>>
在服务器上用Fiddler抓取HTTPS流量
查看>>
文件类似的推理 -- 超级本征值(super feature)
查看>>
【XCode7+iOS9】http网路连接请求、MKPinAnnotationView自定义图片和BitCode相关错误--备用...
查看>>
各大公司容器云的技术栈对比
查看>>
记一次eclipse无法启动的排查过程
查看>>
【转】jmeter 进行java request测试
查看>>
读书笔记--MapReduce 适用场景 及 常见应用
查看>>