Oracle 11g: miglioramenti delle prestazioni degli inserti


8

Ho una tabella di 500 milioni di righe (e in crescita)

Ho fatto quanto segue per migliorare le prestazioni degli inserti:

Dal lato del database:

  • ha eliminato tutti gli indici e i vincoli
  • registrazione disabilitata

Dal lato dell'applicazione:

  • passato da entità gestite JPA a query di inserimento native, aggiunto APPEND suggerimento Oracle alla query
  • ha tentato di eseguire il commit in batch per 1k / 2k / 3k di righe
  • ho provato a scrivere in parallelo (thread multipli, numero thread = al numero core sul server) su una tabella

Questo mi ha dato circa 300 file al secondo

Inoltre provato:

  • scrivere in parallelo in batch su più tabelle (per raggruppare e quindi tornare ai risultati utilizzando UNION)

Questo mi ha dato circa 1k righe al secondo, ma su tabelle vuote. Ma quando ho riempito le tabelle con dati fittizi (200 milioni di ciascuno), la velocità degli inserti è scesa a 250 - 300 al secondo.

Qualcuno potrebbe suggerire cos'altro posso fare per accelerare gli inserti? Fondamentalmente voglio capire qual è (cosa potrebbe essere) il collo di bottiglia per primo.

UPD: la tabella è partizionata per data di inserimento, la tabella ha circa 60 colonne - la maggior parte delle colonne sono VARCHAR2 (2000 BYTE)


Sai che con la registrazione disabilitata, un errore del supporto tra il caricamento e il completamento del primo backup successivo lascerà l'intera tabella, o sezioni di essa nel caso di un inserimento del percorso diretto, irrecuperabile, giusto?
David Aldridge,

1
(1) Solo una sessione può APPENDERE alla volta su un tavolo. (2) il /*+APPEND*/suggerimento viene ignorato sugli inserti a riga singola (se non si ha INSERT INTO ... SELECTproblemi con l'appendice). (3) È necessario impostare un esempio di Caricatore SQL * con direct=trueper stabilire una linea di base come suggerito da @parsifal.
Vincent Malgrat,

Stai utilizzando hardware reale o una macchina virtuale? Se una macchina virtuale, i file del disco sono sparsi (ovvero: non completamente pre-allocati)? Inoltre, modifica la tua domanda con l'output di un statspack o di un rapporto awr (sezione delle attese principali).
Philᵀᴹ

Quale problema / necessità risolve / soddisfa il partizionamento per data di inserimento?
Brian,

Qual è la fonte dei tuoi dati per questa tabella? Si tratta di un caricamento batch da un file ASCII o è generato dall'utente o qualcos'altro. Si prega di essere specifici.
RMAN Express

Risposte:


5

Ho appena visto l'aggiornamento, tabella a 60 col con campi principalmente VARCHAR (2k) - che è (potenzialmente) una tabella di mostri.

Per prima cosa ...

Devi prima capire il tuo collo di bottiglia. Sul lato app, torna indietro alla soluzione di inserimento batch a thread singolo (1/2 / 3k alla volta) e inizia a eseguirla e accedi al computer DB ed esegui un 'top' - vedi quanto tempo impiegato dal processo DB E quanto tempo (se presente) wa% tempo viene visualizzato dalla macchina.

Se top ti mostra QUALSIASI tempo% wa, ciò significa che il tuo DB è associato I / O e probabilmente dovrai prendere in considerazione più macchine DB (shard) o considerare di lanciare SSD sul computer host.

Questo è tutto; la tua ricerca si ferma qui. Non importa quanta CPU stava prendendo il DB o quanto fosse saturo il client dell'app; se si verificano problemi di latenza I / O sul DB host, è più veloce che mai.

SUGGERIMENTO Se le modifiche hardware sono fuori questione, a seconda del filesystem in esecuzione (Linux) è possibile provare a disabilitare la registrazione o la scrittura di metadati per il DB per migliorare leggermente le prestazioni a livello di filesystem. Puoi fare qualcosa di simile su NTFS, ma questo ti darà solo un piccolo impulso. Questo non sarà 2x.

Ora, secondo, secondo ...

Supponiamo che tu abbia avuto quasi nessun tempo% wa ma che la tua CPU sia completamente ancorata dal processo DB. La tua unica opzione ora è quella di introdurre più macchine DB (frammenti) e dividere il lavoro.

Ancora una volta, hai finito con la tua ricerca se questo è il caso. Niente che puoi fare per ottimizzare la CPU per andare più veloce.

Infine, terze cose ... terza ...

Supponiamo che il DB non stia facendo molto. Quindi, vai al computer client che esegue l'inserimento batch e controlla il carico della CPU - è ancorato? In tal caso, accendi alcune altre macchine facendo esattamente gli stessi inserti batch e vedi se riesci a ottenere una rampa lineare.

Se la CPU non è collegata, avvia alcuni altri thread sulla stessa macchina fino a quando non è collegata e vedi come si ridimensiona il DB.

Penso che potresti averlo già provato, quindi la mia ipotesi è che il tuo host client sia già stato ancorato (e più thread non faranno la differenza) o che il DB stia già raggiungendo il suo limite e non può ridimensionare ulteriormente.

appendice

Fare inserimenti non elaborati su una tabella non indicizzata in cui non è presente immondizia è essenzialmente un'operazione APPEND che dovrebbe andare veloce quanto il disco può gestire le scritture.

La creazione di più tabelle sullo stesso computer host non è di alcun aiuto, se non altro consente di cercare il disco (per accedere alle altre tabelle sul disco da aggiungere) e rallentare le cose.

È fondamentale capire prima quel collo di bottiglia, quindi possiamo ottimizzarlo.

Spero che aiuti! Tienici aggiornati.


2
Perché non hai menzionato awr o statspack?
Philᵀᴹ

Con un suggerimento di aggiunta, tutti tranne uno di quei thread saranno inattivi a causa del blocco esclusivo. Non credo che questo codice sia in una fase di efficienza in cui è richiesta un'ottimizzazione a livello di sistema - è la metodologia stessa che è difettosa.
David Aldridge,

Ripensandoci, credo che il tuo approccio abbia un difetto fondamentale. Se Viktors provasse il metodo di inserimento batch a thread singolo e avesse tempi di attesa di I / O, ciò potrebbe essere causato da un metodo di inserimento inefficiente e da un eccesso di commit (la sincronizzazione del file di log attende). Il passo più importante dovrebbe essere quello di capire i meccanismi di Oracle e scegliere prima il più appropriato, sicuramente?
David Aldridge,

@DavidAldridge Viktors ha chiarito che aveva disabilitato la registrazione (e gli indici) dato che, supponevo che non ci fosse molto altro che il DB stava facendo oltre allo streaming dei dati inseriti direttamente nel file della tabella, motivo per cui l'ho fatto saltare direttamente a guardare I / O aspetta. Forse c'è qualcosa in più di Oracle che dovrebbe / potrebbe essere disabilitato - questo è un buon punto di indagine, non conosco le profondità di Oracle abbastanza bene da aiutarlo purtroppo.
Riyad Kalla,

4

Richiamare l'inserimento del percorso diretto con l'hint di accodamento comporta l'esecuzione di un blocco esclusivo sull'intera tabella, pertanto non è utile disporre di più thread che eseguono l'inserimento. Dovresti indirizzare esplicitamente una diversa partizione con ogni inserto ...

insert /*+ append */ into my_table partition (partition_name_1) ...

... per ottenere blocchi esclusivi a livello di partizione. Probabilmente non sarai in grado di farlo con una tabella partizionata alla data di inserimento, molto probabilmente, ma potresti usare il partizionamento composito (non il partizionamento) per ottenere più partizioni per intervallo univoco di date di inserimento.

Non impegnarsi nel mezzo degli inserti, solo alla fine.


Devo menzionare esplicitamente il nome della partizione nella query? Ho una colonna, una specie di tipo di evento. Proverò a partizionare per gruppo di eventi e fare in modo che ogni thread inserisca un batch di righe solo di tipo particolare
deriva il

Per evitare un blocco esclusivo a livello di tabella, sì.
David Aldridge,

Il suggerimento APPEND dovrebbe essere ignorato da Oracle per inserimenti a riga singola. La descrizione del processo da parte dell'OP sembra implicare inserimenti a riga singola in batch. Non sono sicuro di come vengano trattati. Immagino che non ci sia APPEND, ma ha bisogno di alcuni test.
Vincent Malgrat,

Hmmm, non l'ho considerato - è anche peggio, se è così.
David Aldridge,

Vale la pena provare inserti multi-riga con il suggerimento APPEND? Quindi quante voci per inserto su più righe devo inviare?
deriva il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.