【问题标题】:Transfer Huge data using Java使用 Java 传输海量数据
【发布时间】:2014-02-04 02:13:28
【问题描述】:

我需要使用 Java 程序将大量数据(近 1000 万条记录)从一个数据库(oracle)传输到另一个数据库(postgres)。我通过创建与两个数据库的连接并从源数据库查询数据然后通过迭代结果集将数据插入目标数据库来完成相同的操作。但是传输数据需要大量时间。有什么方法可以快速完成转移过程?

【问题讨论】:

  • 您可以使用Spring Batch框架将文件拆分为块和进程。
  • 你和这个人面临同样的问题>>> coderanch.com/t/470765/JDBC/java/Transfer-Huge-data-Java
  • 为什么一定要用Java? Oracle 支持导出到文件,Postgres 支持从文件导入。 Java 不会是我完成这项任务的首选。
  • @EJP 很好...但是我的最终用户要求不是在技术上使用 dbms。最终用户希望一切都带有用户界面。

标签: java jakarta-ee jdbc database


【解决方案1】:

另一种方法是将表中的所有数据导出到一个文本文件中,然后将该数据直接导入到 postgres 中。我不记得 oracle 有什么导出功能,但最坏的情况是你总是可以使用这样的查询,将表的内容转储为一组插入语句:

select '插入 mynewtable 值(' || old.a || ', ' || old.b || ...etc..|| ');'来自 myoldtable old;

我确实在几个小时内处理了来自 Oracle 数据库(使用 Java)的 10MM 记录(每条记录之间进行了大量处理)。你希望有什么样的表现,你现在得到了什么?

当您插入 postgres 表时,您是否检查了很多索引或约束?也许您的代码有其他问题?如果您知道所有行都是有效的,也许您应该在进行插入时删除 postgres 数据库中的约束?

或者,如果您有一段时间没有,也许您需要清理数据库?

【讨论】:

  • 现在我只是使用一些已经从 postgres 中选择的 where 子句从 oracle 读取许多记录,然后再次将所有选择的记录插入到 postgres 中。这需要几个小时。
【解决方案2】:

如果你仅限于单线程读取数据、写入数据,那么改进的空间并不大。

这种类型的性能受到几个不同因素的限制,即通过网络传输的数据量、网络速度、数据库索引和配置以及网络/主机中的其他一些因素。

至少,您应该将读取连接设置为更大的 fetchsize。

ResultSet rs;
...
rs.setFetchSize(500);

在插入方面,您还应该考虑使用 CallableStatement 进行批处理

CallableStatement cs;
Connection conn;
conn.setAutoCommit(false);
... 
cs.addBatch();

if (rowCount % batchsize == 0) {
   int[] updateCounts = cs.executeBatch();

   conn.commit();
   batchCount = 0;

   for (int i = 0; i < updateCounts.length; i++) {
        if (updateCounts[i] < 1)
           bad.write(batchRec[i]);
   }
}

您可以在 Oracle 中为插入性能执行其他操作,其中之一是使用命名管道设置批量加载,然后您的进程可以写入该命名管道。它们是非日志操作,因此速度非常快。我还没有从 Java 中完成命名管道的事情,所以需要研究一下,但这应该会让你继续前进。

你需要弄清楚你的瓶颈在哪里。我已经看到性能随着时间的推移而下降,因为查询是对某个表进行表扫描,并且检索后面行的数据比前面的行需要更长的时间。

与其他任何事情一样,您需要开始引入计时,以查看您的选择是否开始花费更多时间,或者读取性能是否相当稳定(如果后面的行获取时间比前面的行更长,这是一个很好的表扫描指示获取)。

最后,如果您可以巧妙地分解查询,您可以使用多个工作线程来并行处理数据。

即。而不是

select a,b,c from source table

你会像这样分解它

select a,b,c from source table where a < 10;
select a,b,c from source_table where a >= 10 and a < 50;
select a,b,c from source_table where a >= 50;

就像其他任何事情一样,做事有一百种方法。

【讨论】:

    【解决方案3】:

    这里的问题是编程语言使用游标来处理元组集,游标只能遍历它们你不能做批量加载或类似的事情,我认为每一种编程语言都是如此,一个更快的解决方案是连接 Oracle不知何故到 PostgreSQL,我不知道该怎么做,但我认为它应该是可能的。一切都有 Oracle 函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 2012-06-23
      • 2021-02-10
      • 2013-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多