So che altri l'hanno menzionato e non vuoi sentirlo ma usa SQL * Loader o tabelle esterne. Il mio tempo di caricamento medio per tabelle approssimativamente della stessa larghezza è di 12,57 secondi per poco più di 10 m di file. Queste utilità sono state progettate in modo esplicito per caricare rapidamente i dati nel database e sono piuttosto brave in questo. Ciò potrebbe comportare alcune penalità di tempo aggiuntive a seconda del formato del file di input, ma ci sono alcune opzioni e raramente ho dovuto modificare i file prima del caricamento.
Se non sei disposto a farlo, non devi ancora aggiornare il tuo hardware; è necessario rimuovere ogni possibile ostacolo al caricamento rapido. Per enumerarli, rimuovi:
- L'indice
- Il grilletto
- La sequenza
- La partizione
Con tutto ciò stai obbligando il database a svolgere più lavoro e poiché lo stai facendo in modo transazionale, non stai utilizzando il database al massimo delle sue potenzialità.
Carica i dati in una tabella separata, ad esempio ABC_LOAD
. Dopo che i dati sono stati completamente caricati, esegui un singolo istruzione INSERT in ABC.
insert into abc
select abc_seq.nextval, a.*
from abc_load a
Quando lo fai (e anche se non lo fai) assicurati che la dimensione della cache della sequenza sia corretta; per citare:
Quando un'applicazione accede a una sequenza nella cache della sequenza, questi numeri di sequenza vengono letti rapidamente. Tuttavia, se un'applicazione accede a una sequenza che non è nella cache, la sequenza deve essere letta dal disco alla cache prima di utilizzare i numeri di sequenza.
Se le tue applicazioni utilizzano molte sequenze contemporaneamente, la cache delle sequenze potrebbe non essere abbastanza grande da contenere tutte le sequenze. In questo caso, l'accesso ai numeri di sequenza potrebbe spesso richiedere letture del disco. Per un rapido accesso a tutte le sequenze, assicurati che la cache disponga di voci sufficienti per contenere tutte le sequenze utilizzate contemporaneamente dalle tue applicazioni.
Ciò significa che se si dispone di 10 thread che scrivono contemporaneamente 500 record ciascuno utilizzando questa sequenza, è necessaria una dimensione della cache di 5.000. Il documento ALTER SEQUENCE indica come cambiarlo:
alter sequence abc_seq cache 5000
Se segui il mio suggerimento, aumenterei la dimensione della cache a circa 10,5 m.
Cerca di usare il suggerimento APPEND (vedi anche Oracle Base); questo indica a Oracle di utilizzare un inserimento del percorso diretto, che aggiunge i dati direttamente alla fine della tabella anziché cercare lo spazio per inserirli. Non sarai in grado di usarlo se la tua tabella ha indici ma potresti usarlo in ABC_LOAD
insert /*+ append */ into ABC (SSM_ID, invocation_id , calc_id, ... )
select 'c','b',NULL, 'test', 123 , 'N', 'asdf' from dual
union all select 'a','b',NULL, 'test', 123 , 'N', 'asdf' from dual
union all select 'b','b',NULL, 'test', 123 , 'N', 'asdf' from dual
union all select 'c','g',NULL, 'test', 123 , 'N', 'asdf' from dual
Se usi il suggerimento APPEND; Aggiungerei TRUNCATE ABC_LOAD
dopo aver inserito in ABC
altrimenti questa tabella aumenterà indefinitamente. Questo dovrebbe essere sicuro perché a quel punto avrai finito di usare la tabella.
Non menzioni quale versione o edizione o Oracle stai utilizzando. Ci sono una serie di piccoli trucchi extra che puoi usare:
-
Oracolo 12c
Questa versione supporta le colonne di identità; potresti eliminare completamente la sequenza.
CREATE TABLE ABC( seq_no NUMBER GENERATED AS IDENTITY (increment by 5000)
-
Oracle 11g r2
Se mantieni il grilletto; puoi assegnare direttamente il valore della sequenza.
:new.seq_no := ABC_seq.nextval;
-
Edizione Oracle Enterprise
Se stai utilizzando Oracle Enterprise puoi velocizzare INSERT da
ABC_LOAD
utilizzando il suggerimento PARALLEL:insert /*+ parallel */ into abc select abc_seq.nextval, a.* from abc_load a
Ciò può causare i propri problemi (troppi processi paralleli ecc.), quindi prova. potrebbe aiuto per gli inserimenti batch più piccoli, ma è meno probabile che perderai tempo a calcolare quale thread dovrebbe elaborare cosa.
tl;dr
Utilizzare le utilità fornite con il database.
Se non puoi usarli, elimina tutto ciò che potrebbe rallentare l'inserimento e fallo in blocco, perché è in questo che il database è bravo.