2013-08-24 80 views
5

如何在以下步驟中以最佳方式在Oracle中插入超過一百萬行?如果我將FOR循環增加到一百萬行,它會掛起。在Oracle中插入一百萬行的最快方法

create or replace procedure inst_prc1 as 
    xssn number; 
    xcount number; 
    l_start Number; 
    l_end Number; 
    cursor c1 is select max(ssn)S1 from dtr_debtors1; 

Begin 
    l_start := DBMS_UTILITY.GET_TIME; 
    FOR I IN 1..10000 LOOP 
    For C1_REC IN C1 Loop 
     insert into dtr_debtors1(SSN) values (C1_REC.S1+1); 
    End loop; 
    END LOOP; 
    commit; 
    l_end := DBMS_UTILITY.GET_TIME; 
    DBMS_OUTPUT.PUT_LINE('The Procedure Start Time is '||l_start); 
    DBMS_OUTPUT.PUT_LINE('The Procedure End Time is '||l_end); 
End inst_prc1; 
+0

我不建議使用光標。光標會降低你的表現。 –

+0

選中此鏈接(http://www.orafaq.com/wiki/Oracle_Row_Generator_Techniques) – haki

回答

5

您的方法會導致內存問題。最快的方式將是[查詢大衛的評論後編輯照顧空場景]:

insert into dtr_debtors1(SSN) 
select a.S1+level 
    from dual,(select nvl(max(ssn),0) S1 from dtr_debtors1) a 
connect by level <= 10000 

一個選擇Insert是一切都保持在RAM中的最快方法。 如果該查詢滑入全局臨時區域,則該查詢可能會變慢,但需要進行數據庫調整。我認爲沒有比這更快的東西。

很少內存使用的詳細信息通過查詢:

每個查詢都會有自己的PGA [程序全局區],它基本上是可用RAM每個查詢。如果這個區域不足以返回查詢結果,那麼SQL引擎開始使用Golabl臨時表空間,這就像硬盤一樣,查詢開始變慢。如果查詢所需的數據非常龐大,即使臨時區域不夠用,您也會出現表空間錯誤。

因此,總是設計查詢,以便它停留在PGA,否則它將成爲紅旗。

+1

該查詢不會使用臨時表空間,它會因'ORA-30009:首次沒有足夠的內存用於CONNECT BY操作'而失敗。這很奇怪,因爲你可以通過'alter session set workarea_size_policy = manual;'和'alter session set sort_area_size = ;來解決錯誤。顯然不是所有的「排序」都可以使用臨時表空間。 –

+0

如果dtr_debtors1是空的,那麼你要插入空值到表中。使用合併(max(ssn),0)。 –

2

一次插入一行,單循環內的單個insert語句很慢。最快的方法是使用insert-select,如下所示,它會生成一百萬行和批量插入。

insert into dtr_debtors1(SSN) 
select level from dual connect by level <= 1000000; 
+0

這不是正確的解決方案。查看我的回答 – Lokesh

+0

感謝lokiIts爲此鏈接工作 – user1016594

0

嘗試刪除你的桌子上創建的所有索引,然後嘗試使用select查詢插入。你可以嘗試這個鏈接,這將幫助你在inserting millions of rows快速進入你的數據庫。

+0

-1。過時的,不相關的和可疑的內容。 –

相關問題