2008-12-13 60 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有幾個例子。

//尼古拉斯