如何提高大型文本文件的数据加载性能[重复]

Posted

技术标签:

【中文标题】如何提高大型文本文件的数据加载性能[重复]【英文标题】:How do I increase performance on data load for large text file [duplicate] 【发布时间】:2017-10-27 14:13:36 【问题描述】:

我正在尝试将一个大文本文件插入到 oracle 数据库中,我当前的程序可以运行,但加载速度很慢。 文本文件大约 400 MB

我所做的如下所示......

...
ArrayList<String> nta = new ArrayList<String>();
while ((line = br.readLine()) != null) 
//add data position for each line read
data.add(line.substring(0, 6)+
"="+line.substring(6, 24)+
"="+line.substring(24, 30)+
"="+line.substring(30, 48)); 


db.insertRecord(data);
...

public void insertRecord(ArrayList<String> data) 
String sql = "Insert into Account (NAME, ID, RCBS, CA_NUM, GUID, PARN_GUID)"+
             " values "
             "(?,?,?,?,?,?)";
...
ps = con.prepareStatements(sql);
for(int i=0; i<data.size(); i++) 
    String[] fields = data.get(i).split("=");
            ps.setString(1, fields[0]);
            ps.setString(2, fields[1]); 
            ps.setString(3, fields[2]);
            ps.setString(4, fields[3]); 
            ps.setString(5, fields[0].trim()+"."+fields[1].trim()+"."+fields[2].trim()+"."+fields[3].trim()); //Index
            ps.setString(6, fields[0].trim()+"."+fields[1].trim()); //PARN Index
            ps.execute();
 //end loop
con.commit();
...

有没有什么性能可以提高数据加载的速度?

【问题讨论】:

使用批量插入。 请停下来,以正确的方式去做。例如使用 SQL*Loader 或外部表。 我遇到的问题是文本文件中有一个奇怪的 ascii 字符。当我使用 SQL 加载器时,它会将其加载为 > 在表列中 使用 @CrazySabbath 的方法,我遇到了类似的问题。我闯入了“块”——我实际上构建了一个异步 api(将利用多个线程)来处理我们的文档处理——有点矫枉过正,但学习过程很棒哈哈 嗨 - 通过 java 插入“奇怪的 ascii 字符”会发生什么?我希望您可以通过在 SQLLDR 中指定字符集来加快速度,例如 LOAD DATA CHARACTERSET MSWIN1252 【参考方案1】:

按照建议,您应该在处理这么多记录时使用批量插入。请注意,这段代码将每 1000 次(不是一次全部)执行一次插入,以避免可能的内存问题,batchInterval

int batchInterval = 1000;

ps = con.prepareStatements(sql);
for(int i=0; i<data.size(); i++) 
        String[] fields = data.get(i).split("=");
        ps.setString(1, fields[0]);
        ps.setString(2, fields[1]);
        ps.setString(3, fields[2]);
        ps.setString(4, fields[3]);
        ps.setString(5, fields[0].trim()+"."+fields[1].trim()+"."+fields[2].trim()+"."+fields[3].trim()); //Index
        ps.setString(6, fields[0].trim()+"."+fields[1].trim()); //PARN Index
        ps.addBatch();

        if (i % batchInterval == 0) ps.executeBatch();


ps.executeBatch();
ps.close();
con.close();

您可以在这里找到更多信息:batch inserts tutorial

【讨论】:

【参考方案2】:

将其作为 CLOB(一部分中的多行)发送到服务器并在服务器端解析..

【讨论】:

你是在建议他在 oracle 数据库上解析 400MB 大小的 CLOB 吗? 为什么不呢?部分 32 KB。非常有效地代替了 100,000 个单独的插入。这样我每月在生产数据库中最多导入 10 GB 的 csv 文件

以上是关于如何提高大型文本文件的数据加载性能[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在处理西里尔文文本文件时提高 C++ 性能?

使用 Pandas 读取大型文本文件 [重复]

解析大型文本文件最终导致内存和性能问题

通过消除重复将数据从文本文件加载到mysql数据库

C++ 和读取大型文本文件

如何获取大型文本数据文件的统计信息