2008-12-13 55 views
1

由于我启动了从一个表插入7M行到另外两个表的过程,现在我想知道是否有更快的方法来做到这一点。预计该过程将在一个小时内完成,即24小时处理。更快插入Oracle散列簇表

这是怎么一回事呢:

从该表

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(); 

有什么想法?

回答

3

我推荐的第一件事是做一个简单的insert-select语句,让数据库处理所有的数据移动。如果您要在两台机器之间移动数据,或者如果您没有足够大的回滚段来处理整个查询,那么它就不那么有用。

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

第三,除非在目标表中已经有很多行,否则在插入之前删除所有索引,然后重新创建。如果将索引保留就位,则必须对每行进行更新,以增加脏块开销。

最后:你需要聚簇表吗?我的经验是,他们不会给你买很多东西(说明:这种体验是在一个表空间上的)。

+0

嘿感谢您的建议。我使用Java来监视数据传输过程(剩下多少行),普通的INSERT AS SELECT不会告诉我。我总是以相同的方式访问表,如select * from T1 where word ='foo';对于那个哈希表我觉得最好。 – chris 2008-12-15 02:36:39

0

除非你有特殊的理由来处理应用程序中的数据,否则我会直接使用INSERT AS SELECT。 使用并行DML可以给你带来巨大的差异。

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

除非你有IO问题,1H应该是绰绰有余......

问候

1

嗯,你不能调用Oracle中的表RAW - 这是一个保留字这么一个ORA-将会引发00903错误。

不谈,你会使用:

insert all 
into t1 
into t2 
select * from RAW 
/

“行由行等于慢的慢” :)

0

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

//尼古拉斯