2011-08-17 8 views
5

Nei giorni scorsi ho giocato con Oracle SQL Loader nel tentativo di caricare i dati in massa in Oracle. Dopo aver provato diverse combinazioni di opzioni, sono rimasto sorpreso nel constatare che il carico del percorso convenzionale è molto più rapido del carico diretto del percorso.Il caricatore Oracle SQL * in esecuzione in modalità diretta è molto più lento del carico di percorso convenzionale

alcuni fatti circa il problema:

  • Numero di record da carico è 60K.
  • Il numero di record nella tabella di destinazione, prima del caricamento, è 700 milioni.
  • La versione Oracle è 11g r2.
  • Il file di dati contiene data, carattere (ascii, nessuna conversione richiesta), intero, float. Nessun blob/clob.
  • La tabella è partizionata da hash. La funzione hash è uguale a PK.
  • Parallel of table è impostato su 4 mentre il server ha 16 CPU.
  • L'indice è partizionato localmente. Parallel of index (from ALL_INDEXES) è 1.
  • C'è solo 1 indice PK e 1 sulla tabella di destinazione. Vincolo PK costruito usando l'indice.
  • Il controllo delle partizioni indice ha rivelato che la distribuzione dei record tra le partizioni è piuttosto uniforme.
  • Il file di dati è delimitato.
  • L'opzione APPEND è utilizzata.
  • Selezionare e cancellare i dati caricati tramite SQL è una risposta piuttosto veloce, quasi istantanea.

Con il percorso convenzionale, il caricamento è completato in circa 6 secondi.

Con il carico di percorso diretto, il caricamento richiede circa 20 minuti. La peggiore esecuzione richiede 1,5 ore a completa, ma il server non era affatto occupato.

Se skip_index_maintenance è abilitato, il carico del percorso diretto viene completato in 2-3 secondi.

Ho provato un certo numero di opzioni ma nessuna di esse offre un miglioramento notevole ... NON RIPROVERSABILE, INDICE SORTED, MULTITHREADING (Sto eseguendo SQL * Loader su un server con più CPU). Nessuno di loro migliora la situazione.

Ecco l'evento di attesa Continuavo a vedere durante il tempo di SQL * Loader viene eseguito in modo diretto:

  • evento: DB file sequenziali di lettura
  • P1/2/3: File #, Block #, blocchi (controllare da dba_extents che si tratta di un blocco di indice) classe
  • Attendere: I/O utente

qualcuno ha qualche idea di cosa è andato storto con carico percorso diretto? O c'è qualcosa che posso ulteriormente controllare per scavare davvero la causa principale del problema? Grazie in anticipo.

risposta

3

immagino state cadendo uccelli questo

"Quando si carica un numero relativamente piccolo di righe in una grande tabella indicizzata

Durante un carico percorso diretto, l'indice esistente viene copiato quando viene fusa con le nuove chiavi dell'indice Se l'indice esistente è molto grande e il numero di nuove chiavi è molto piccolo, allora il tempo di copia dell'indice può compensare il tempo risparmiato da un carico di percorso diretto. "

da Quando utilizzare un carico percorso convenzionale in: http://download.oracle.com/docs/cd/B14117_01/server.101/b10825/ldr_modes.htm

+0

Sai che il comportamento non si verificano solo per SQL Loader o lo fa comporti allo stesso modo con inserto aggiungere? Ho fatto un test molto rapido e non sembrava copiare il mio indice esistente (circa 92Meg) quando ho inserito 100 righe con l'append hint. –

+0

Non ne ho idea, immagino che se provassi ad inserire le righe di accodamento 60k mostrerebbe lo stesso comportamento –

+0

Grazie Kevin. Ho completamente perso quella sezione quando scrivo il documento di SQL * Loader. Ma quale potrebbe essere il modo migliore per caricare una grande quantità di dati in una tabella non vuota con una quantità relativamente grande di record? – Stanley