首页 > 解决方案 > JDBC 准备好的语句,没有大的列导致性能瓶颈。ETL 工具如何规避这个问题?

问题描述

主要是一个 DB 人,没有使用 java 进行批量加载等,因为这些是由 ETL 工具或 DB 内部工具完成的。

但如果我理解正确,工具是由 Java/C++ 等编写的,它们使用 JDBC、ODBC 来实现操作。

最近在一个项目中尝试使用 JDBC 加载批量数据并观察到以下情况。

我们有 100 万条记录,1.5 Gb 的数据,表有 360 列。从表 A 中读取并尝试在 5k 记录批处理模式间隔中插入目标表。源 abd 目标是 Oracle。

该项目使用 Spring JDBC。我在这里使用了简单的 JDBC 来单独测试和调试性能问题。用伪语言描述的逻辑。

prepare statement for Target with 
"insert into target values ( ?,?, .. 368 columns);
rs = (  select * from table a );
while rs.next {
  stmt.setstring(1, rs.getString("column1");
 .
 .
 360 columns.
 stmt.add_batch();

 if 5K records then executeBatch();
}

主要问题:

对于每 5K 条记录,设置的 Statements 大约需要 1 分钟以上。

因此仅加载 1.5 Gb 或 100 万条记录将需要大约。4个小时。

我在一个线程中执行此操作,但我觉得音量非常低。有没有更好的方法来实现这一点?

ETL 工具如何说 informatica 等在内部实现?

另一个问题是:有时executeBatch()对于某些列数相似且每条记录的容量更大的表,一次写入 5k 条记录。在某些情况下,它一次写入 100 条记录,尽管executeBatch是在 5k 行之后,并且写入也需要永恒的 100 万条记录。

如果我使用 set 语句作为另一件事而不是结果集

for (I=1 ,I<=1000000; I++)
  stmt.setstring(1, rs.getString("123456789");--hardcode value
    .
    .
    360 columns.
   stmt.add_batch();
  if 5K records then executeBatch();
}

然后每 5k 和 2-3 秒绑定到executeBatch(). 所以在 20 分钟内,我能够加载 100 万个大约 6-7 GB 的数据。

标签: oraclejdbc

解决方案


推荐阅读