SQL Server中采用BULK INSERT实现大数据量文本文件批量导入

今天做了一个基于SQL Server的文本文件批量导入工具,和大家分享一下心得。 

方案一:

遍历文本文件,解析每一行,形成SQL语句后向数据库插入。

方案二

遍历文本文件,解析每一行,将SQL语句保存到文本文件然后执行。

方案三

使用SQL Server Bulk Insert功能披露导入数据,然后在数据库中做数据处理。

刚开始用方案一做的,50MB文本文件导入大约20-25分钟,后来进行了优化,采用数据批量插入,性能提升不大。

继续优化,使用多线程向数据库中插入数据,性能提升10-20%左右,效果也不好。

 

方案二没有完全测试,主要是生成SQL文件耗时15分钟左右,不太理想。

最后使用BULK INSERT,然后在数据库中写脚本对数据进行处理,50MB文件10秒即可导入

    FQuery.SQL.Text := 'BULK INSERT LOGDATA FROM ' + QuotedStr(FFileName)
      + ' WITH (FIELDTERMINATOR = '','', ROWTERMINATOR = ''/n'',  BATCHSIZE = 500)';
    FQuery.ExecSQL;

最后执行大量的UPDATE语句,将数据格式化

建议在做大数据量导入的时候还是用BULK INSERT ,SQL SERVER 性能在那里摆着,一个SQL 4ms,1000行就要4秒,根本快不了

 

 

 

测试java的insert 同使用9i以后的bulk Insert 的速度.
测试结果显示通过bulk Insert 速度相当的快.
100000条记录
insert ,---------------93秒
bulk insert -------------0.441秒

环境:
oracle 10.2.0.3 Windows 2000Server
java
代码:
SQL> desc a
Name Type Nullable Default Comments
---- ------------ -------- ------- --------
ID INTEGER Y
NAME VARCHAR2(20) Y

bulk Insert 使用的类型及过程
create or replace type i_table is table of number(10);
create or replace type v_table is table of varchar2(10);

create or replace procedure pro_forall_insert(v_1 i_table,v_2 v_table)
as
c integer;
begin

forall i in 1.. v_1.count
insert into a values(v_1(i),v_2(i));
end;
测试的java代码:
public class testOracle {
public testOracle() {

Connection oraCon = null;
PreparedStatement ps = null;
Statement st = null;
ResultSet rs = null;
try {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException ex) {}
oraCon = DriverManager.getConnection("jdbc:oracle:thin:@192.168.15.234:1521:ora10g", "imcs","imcs");
oraCon.setAutoCommit(false);
} catch (SQLException ex) {
ex.printStackTrace();
}

CallableStatement cstmt = null;
oracle.sql.ArrayDescriptor a = null;
oracle.sql.ArrayDescriptor b = null;
if (1 == 1 )
{
Object[] s1 = new Object[100000];
Object[] s2 = new Object[100000];

for (int i = 0; i < 100000; i++) {
s1[i] = new Integer(1);
s2[i] = new String("aaa").concat(String.valueOf(i));
}
try {
a = oracle.sql.ArrayDescriptor.createDescriptor("I_TABLE", oraCon);
b = oracle.sql.ArrayDescriptor.createDescriptor("V_TABLE", oraCon);
ARRAY a_test = new ARRAY(a, oraCon, s1);
ARRAY b_test = new ARRAY(b, oraCon, s2);
cstmt = oraCon.prepareCall("{ call pro_forall_insert(?,?) }");
cstmt.setObject(1, a_test);
cstmt.setObject(2, b_test);
long aaaa = System.currentTimeMillis();
System.out.println(System.currentTimeMillis());
cstmt.execute();
oraCon.commit();
System.out.println(System.currentTimeMillis()-aaaa);
} catch (Exception e) {
e.printStackTrace();
}
}
else
{
try
{
PreparedStatement oraPs = null;
String oraInsertSql =
"insert into a values(?,?)";

oraPs = oraCon.prepareStatement(oraInsertSql);
long aaaa = System.currentTimeMillis();
System.out.println(System.currentTimeMillis());
for (int i = 0; i < 100000; i++)
{

oraPs.setInt(1,i);
oraPs.setString(2, new String("aaa").concat(String.valueOf(i)));
oraPs.executeUpdate();
}
oraCon.commit();
System.out.println(System.currentTimeMillis()-aaaa);
}
catch (SQLException ex)
{
System.out.print("dddddd");
System.out.print(ex.getMessage());
}

}
try {
jbInit();
} catch (Exception ex) {
ex.printStackTrace();
}
}


public static void main(String args[]) {
testOracle a = new testOracle();
}

private void jbInit() throws Exception {
}


};

posted @ 2013-12-16 11:01  Net-Spider  阅读(445)  评论(0编辑  收藏  举报