2013-08-24 3 views
5

Come posso inserire più di un milione di righe in Oracle in modo ottimale per la seguente procedura? Si blocca se aumento il ciclo FOR su un milione di righe.Il modo più veloce per inserire un milione di righe in 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

Non mi consiglia di utilizzare il cursore per questo. Come il cursore diminuirà la tua performance. –

+0

Controlla questo [collegamento] (http://www.orafaq.com/wiki/Oracle_Row_Generator_Techniques) – haki

risposta

5

Il tuo approccio porterà a problemi di memoria. Il modo più veloce sarà questo [Query modificato dopo il commento di David per prendersi cura di scenario null]:

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 

Un inserto di selezione è l'approccio più veloce come tutto rimane in RAM. Questa query può diventare lenta se scivola nell'area di temperatura globale, ma in tal caso è necessario il tuning del DB. Non penso che ci possa essere qualcosa più veloce di questo.

qualche dettaglio in più su l'uso della memoria di query:

Ogni query avrà la propria PGA [zona globale Programma] che è fondamentalmente RAM disponibile per ogni query. Se questa area non è sufficiente per restituire i risultati della query, il motore SQL inizia a utilizzare il tablespace Temp Golabl, che è come il disco rigido e la query inizia a rallentare. Se i dati necessari per la query sono così grandi che anche l'area temporanea non è sufficiente, si verificherà un errore di tablespace.

Quindi, sempre la query di progettazione in modo che rimanga in PGA altrimenti è una bandiera rossa.

+1

Questa query non utilizzerà tablespace temporaneo, fallirà con 'ORA-30009: Memoria insufficiente per operazione CONNECT BY'. Il che è abbastanza strano dal momento che è possibile risolvere l'errore con "alter session set workarea_size_policy = manual;" e "alter session session sort_area_size = ;". Apparentemente non tutti i "tipi" possono usare tablespace temporaneo. –

+0

Se dtr_debtors1 è vuoto, allora inserirai i null nella tabella. Usa Coalesce (max (ssn), 0). –

2

L'inserimento di una riga alla volta con la singola istruzione insert all'interno del ciclo è lenta. Il modo più veloce è utilizzare insert-select come il seguente, che genera un milione di righe e un inserimento di massa.

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

Questa non è la soluzione corretta. Vedere la mia risposta – Lokesh

+0

Grazie a chi lavora – user1016594

0

tenta di eliminare tutti i indice creato sulla vostra tavola e quindi provare a inserire utilizzando la query select. Puoi provare questo link che ti aiuterà in inserting millions of rows velocemente nel tuo database.

+0

-1 per quel collegamento. Contenuto obsoleto, irrilevante e discutibile. –