由于我开始从一个表中插入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();
有什么想法吗?
答案 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有一些例子。
//尼古拉斯