【问题标题】:Insert many rows to Oracle Database very fast向 Oracle 数据库中快速插入多行
【发布时间】:2011-11-15 07:23:54
【问题描述】:

我需要非常快地将许多 sql 行插入到 oracle 数据库中。 IndexData 是包含保存方法的类,可以插入到 oracle 数据库中。

while ((line = in.readLine()) != null) {
    if(line.contains("numDocs")) {
        numDocs = in.readLine().trim();
//For Inserting 
IndexData id = new IndexData(timeStamp, 1, 2, numcDocs);
id.save();
    }  else if(line.contains("indexSize")) {
        indexSize = in.readLine().trim();
//For Inserting 
IndexData id = new IndexData(timeStamp, 1, 3, indexSize);
id.save();
        } else if(line.contains("indexReplicatedAt")) {
   replicationTime = in.readLine().trim();           
//For Inserting         
IndexData id = new IndexData(timeStamp, 1, 4, replicationTime );
id.save();
    } 
    }

    BufferedReader inUrl   = new BufferedReader (new InputStreamReader (isUrl));
    String lineUrl;
    Pattern regex = Pattern.compile("<str name=\"status\">(.*?)</str>");

    while ((lineUrl = inUrl.readLine()) != null) {
    if(lineUrl.contains("str name=\"status\"")) {
        Matcher regexMatcher = regex.matcher(lineUrl);
        if (regexMatcher.find()) {
        status = regexMatcher.group(1);
//For Inserting
IndexData id = new IndexData(timeStamp, 1, 5, status);
id.save();
        }                   


}  
}

这是我的 IndexData 类-

public IndexData(String timestamp, String serveId, String informationId, String value ) {
this.timestamp=timestamp;
this.serverId=serverId;
this.informationId=informationId;
this.value=value;
}
//For Inserting
public void save() throws SQLException {

ps = DataSource.conn.prepareStatement (
"INSERT INTO table(timestamp, serverId, informationId, value) VALUES(?,?,?,?)");

ps.setString (1, timestamp);
ps.setString (2, serverId);
ps.setString (3, informationId);
ps.setString (4, value);

ps.executeUpdate();
ps.close ();
}

这是插入具有多个用于插入的多个 sql 语句的 oracle 数据库的最佳方法吗?因为我一次又一次地打开 IndexData 类,以便为每个信息只插入一行到 DB 中。有没有比这更快的方法。任何建议将不胜感激..

【问题讨论】:

  • “许多”是多少?阻碍?数千?百万?

标签: java sql oracle jdbc


【解决方案1】:

看看PreparedStatement.addBatchPreparedStatement.executeBatch - 你可以创建一个准备好的语句,为执行添加几组参数,然后执行批处理。不过,您可能希望为每批选择一定数量的插入,从而限制在内存中累积的“待处理”工作量。

【讨论】:

  • 感谢您的信息。你能根据我的代码举个例子吗?根据您的建议,我必须修改 IndexData 类中的保存方法。对吗?
  • @RaihanJamal:您需要更改代码以将save 方法移出IndexData,或者在IndexData 中使用静态方法来保存List&lt;IndexData&gt; 或其他内容相似的。该方法将准备语句,然后循环要添加的项目,设置参数并多次调用addBatch,然后调用executeBatch - 可能在循环中执行所有以限制批量大小。
  • @Jon Skeet 您需要每 xxxx 条记录(1000 条或更多)执行/清除批处理,以最大限度地减少内存使用量。
  • @SergeyGazaryan:是的,所以我的最后一句话:)
【解决方案2】:

这永远不会很好地扩展,但这取决于需要加载多少记录。通常,更好的选择是使用直接路径加载和 sql 加载器并可能并行加载。

【讨论】:

  • +1 Oracle 提供了几种将信息从文件加载到数据库的方法:SQL 加载器和外部表是常用的方法。使用提供的功能的面向批量的方法总是比手动 RBAR 实现更快,无论调整得多么好。
【解决方案3】:

我觉得你的设计有不好的味道,比如你的实体对象负责创建和关闭准备语句,数据库连接是“全局的”等等。

有一些常见的方法可以查看:

  1. 只执行一次准备语句,并使用它进行多次更新
  2. 使用批量插入/更新

然而,这两种方式都需要你重新审视你的设计(但我认为这样做是值得的)。

(而且,如果您要发布代码,请确保正确缩进。现在简直是一团糟)

【讨论】:

    【解决方案4】:

    您可以做的一件事是将查询写入文件并在单独的线程中将文件加载到数据库中。 这是因为您所有的查询都只是插入查询。这有一个小故障,虽然如果文件加载失败,那么你不知道它错在哪里。我猜这样可以减少内存占用并更快地工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-14
      • 2017-09-08
      • 1970-01-01
      • 2018-09-10
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 2014-02-10
      相关资源
      最近更新 更多