更快地插入Oracle哈希群集表

时间:2008-12-13 12:41:38

标签: java oracle insert hashtable cluster-computing

由于我开始从一个表中插入7M行到另外两个表的过程,我现在想知道是否有更快的方法来执行此操作。预计该过程将在一小时内完成,即处理24小时。

这是怎么回事:

此表中的数据

RAW (word VARCHAR2(4000), doc VARCHAR2(4000), count NUMBER);

应该在另外两个集群表T1和T2

中找到新的住宅
CREATE CLUSTER C1 (word VARCHAR2(4000)) SIZE 200 HASHKEYS 10000000;
CREATE CLUSTER C2 (doc VARCHAR2(4000)) SIZE 200 HASHKEYS 10000000;

T1 (word VARCHAR2(4000), doc VARCHAR2(4000), count NUMBER) CLUSTER C1(word);
T2 (doc VARCHAR2(4000), word VARCHAR2(4000), count NUMBER) CLUSTER C2(doc);

通过Java插入手动提交,如下

stmtT1 = conn.prepareStatement("insert into T1 values(?,?,?)");
stmtT2 = conn.prepareStatement("insert into T2 values(?,?,?)");

rs = stmt.executeQuery("select word, doc, count from RAW");

conn.setAutoCommit(false);

while (rs.next()) {
    word = rs.getString(1);
    doc = rs.getString(2);
    count = rs.getInt(3);

    if (commitCount++==10000) { conn.commit(); commitCount=0; }

    stmtT1.setString(1, word);
    stmtT1.setString(2, doc);
    stmtT1.setInt(3, count);

    stmtT2.setString(1, doc);
    stmtT2.setString(2, word);
    stmtT2.setInt(3,count);

    stmtT1.execute();
    stmtT2.execute();
}

conn.commit();

有什么想法吗?

4 个答案:

答案 0 :(得分:3)

我建议的第一件事是做一个简单的insert-select语句,让数据库处理所有的数据移动。如果您在两台计算机之间移动数据,或者如果没有足够大的回滚段来处理整个查询,则不太有用。

我要了解addBatch()方法的第二件事。在编写代码时,它会为您插入的每一行进行数据库往返,这会增加网络开销。

第三,除非目标表中已经有很多行,否则在插入之前删除任何索引,然后重新创建。如果保留索引,则必须为每一行更新它们,从而增加脏块开销。

最后:你需要聚集表吗?我的经验是他们不会给你买太多(告诫:那次经历是在一个表空间上)。

答案 1 :(得分:1)

好吧,你不能在Oracle中调用表RAW - 它是一个保留字,因此会引发ORA-00903错误。

除此之外,你会使用:

insert all
into t1
into t2
select * from RAW
/

“逐行等于慢 - 慢”:)

答案 2 :(得分:0)

除非您有特殊原因要在应用中处理数据, 我会直接插入INSERT AS SELECT。 使用Parallel DML可以给你带来巨大的变化。

如果符合您的需要,还要检查INSERT ALL语法(1次读取2次写入)。

除非你有IO问题,否则1h应该绰绰有余......

此致

答案 3 :(得分:0)

在概念上类似于addBatch,您可以编写一个接受(word,doc,count)数组的PL / SQL过程并处理服务器端的插入。它在概念上是相似的,因为您通过一次发送多个记录来减少网络跳闸,并且您可以实现更快的性能。另一方面,它更复杂和脆弱,因为它需要在服务器端编写PL / SQL,并且在客户端需要额外的数组逻辑。 Oracle TechNet有一些例子。

//尼古拉斯