2013-08-24 15 views
5

Jak mogę wstawić ponad milion wierszy w Oracle w optymalny sposób dla następującego procdeure? Zawiesza się, jeśli zwiększę pętlę FOR do miliona wierszy.Najszybszy sposób wstawienia miliona wierszy w 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

Nie polecam używania do tego celu kursora. Ponieważ kursor zmniejszy Twoją wydajność. –

+0

Sprawdź to [link] (http://www.orafaq.com/wiki/Oracle_Row_Generator_Techniques) – haki

Odpowiedz

5

Twoje podejście prowadzi do problemów z pamięcią. Najszybszym sposobem będzie to [Zapytanie edytować po komentarza Dawida dbać o zerowej scenariuszu]:

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 

Wybrana wkładka jest najszybszy podejście jak wszystko pozostaje w pamięci RAM. Ta kwerenda może stać się wolna, jeśli zostanie zmieniona na Globalny obszar tymczasowy, ale wówczas będzie wymagać dostrojenia DB. Nie sądzę, żeby mogło być coś szybciej niż to.

kilka szczegółów na temat wykorzystania pamięci przez zapytanie:

Każde zapytanie będzie miała swój własny globalny obszar PGA [PROGRAM], który jest w zasadzie pamięci RAM dostępnej dla każdego zapytania. Jeśli ten obszar nie jest wystarczający do zwrócenia wyników kwerend, silnik SQL rozpoczyna korzystanie z tabeli punktów, która jest jak twardy dysk, a zapytanie zaczyna się powoli. Jeśli dane wymagane przez zapytanie są tak duże, że nawet tymczasowy obszar nie jest wystarczający, to błąd tabeli będzie błędny.

Zawsze należy więc projektować zapytanie, aby pozostało ono w PGA innym kolorze czerwonym.

+1

Ta kwerenda nie użyje tymczasowego obszaru tabel, zakończy się niepowodzeniem z "ORA-30009: Za mało pamięci dla operacji CONNECT BY". Co jest dość dziwne, ponieważ możesz rozwiązać błąd przez 'alter session set workarea_size_policy = manual;' i 'alter session set sort_area_size = ;'. Najwyraźniej nie wszystkie "sortowania" mogą korzystać z tymczasowego obszaru tabel. –

+0

Jeśli dtr_debtors1 jest pusty, wtedy wstawisz wartości null do tabeli. Użyj Coalesce (max (ssn), 0). –

2

Wstawianie pojedynczego wiersza za pomocą pojedynczej instrukcji insert w pętli jest wolne. Najszybszym sposobem jest użycie insert-select jak poniżej, który generuje milion wierszy i wkładkę luzem.

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

To nie jest poprawne rozwiązanie. Zobacz moją odpowiedź – Lokesh

+0

Dzięki lokiIts pracy – user1016594

0

Spróbuj upuść cały indeks tworzony na stole, a następnie spróbuj wstawić przy użyciu kwerendy select. Możesz wypróbować ten link, który pomoże Ci szybko wejść do bazy danych.

+0

-1 dla tego łącza. Nieaktualna, nieistotna i wątpliwa treść. –

Powiązane problemy