Inserimento InnoDB più veloce


8

Sono uno studente di scuola di specializzazione alla ricerca di OLAP con Mondrian OLAP. Quindi voglio inserire i dati in InnoDB (MySQL 5.5) più velocemente al caricamento iniziale. In questo ambiente, l'unico utente sono io, quindi penso che possa consentire impostazioni più lente per la velocità di inserimento. Al momento, sto usando le seguenti tecniche.

  • disattivare log_bin
  • abilitare skip-innodb-doublewrite
  • impostato transaction_isolationsu READ-COMMITTEDo READ-UNCOMMITTED(effettivamente READ-COMMITED)
  • impostato innodb_flush_log_at_trx_commitsu 0o 2(effettivamente 0)
  • impostato innodb_buffer_pool_sizesu 5 GB (il sistema ha 6 GB di RAM)

Ci sono altre tecniche per un inserimento più veloce su InnoDB? E devo modificare innodb_io_read_threade innodb_io_write_thread? Se hai bisogno di maggiori informazioni, per favore dimmelo.

Risposte:


9

SUGGERIMENTO # 1

Se la macchina ha più core, è necessario aumentare quanto segue:

[mysqld]
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000

Cosa sono questi?

  • innodb_read_io_threads - Il numero di thread I / O per le operazioni di lettura in InnoDB.
  • innodb_write_io_threads - Il numero di thread I / O per le operazioni di scrittura in InnoDB.
  • innodb_io_capacity - Un limite superiore per l'attività I / O eseguita dalle attività in background di InnoDB, come lo svuotamento delle pagine dal pool di buffer e l'unione dei dati dal buffer di inserimento.

SUGGERIMENTO # 2

Per separare i dati e gli indici dal tablespace di sistema (ibdata1), è necessario eseguire una ristrutturazione completa di InnoDB. Sembra complicato, ma è molto semplice. Ne ho scritto in StackExchange DBA (29 agosto 2012) e StackOverflow (29 ottobre 2010) . I passaggi di base sono

  • Correre SET GLOBAL innodb_fast_shutdown = 0;
  • mysqldump tutti i dati in un dump SQL
  • service mysql stop
  • Elimina i seguenti file
    • ibdata1
    • ib_logfile0
    • ib_logfile1
  • service mysql start

Prima di eseguire service mysql start, aggiungi questa riga amy.cnf

innodb_open_files=32768

In questo modo, ci saranno handle di file dedicati a ciascuna singola tabella. L'impostazione predefinita è 300. È noto che gli handle di file vengono memorizzati nella cache. Ci sarà un rallentamento se si imposta questo valore molto alto e si colpisce rapidamente il soffitto . Questo non dovrebbe essere il caso se stai lavorando su un numero limitato di tabelle.


Grazie per i vostri suggerimenti. Cercherò suggerimento # 2 in questo momento, e io regolare innodb_read_io_threads, innodb_write_io_threadse `innodb_io_capacity'.
inohiro,

"Elimina i seguenti file ibdata1" Sheesh, senza preavviso.
Magallanes,

6

C'è un intero documento dedicato al caricamento collettivo di dati in InnoDB. I punti principali:

  1. disabilita autocommit per evitare un ulteriore log flush per ogni istruzione insert: SET autocommit=0;...sql import;COMMIT;
  2. disabilitare i controlli esterni e unici (non è possibile disabilitare completamente tutti gli indici):

    SET unique_checks=0;
    SET foreign_key_checks=0;
    
  3. Potenzialmente impostare innodb_autoinc_lock_mode su 2, anziché su 1 (impostazione predefinita). Ecco la documentazione su questa impostazione.

Il terzo potrebbe aiutarti o meno, quindi ti suggerisco di leggere quel link per vedere come stai caricando i dati inizialmente. Ad esempio, se si stanno suddividendo i carichi in più inserti per l'esecuzione simultanea, sarà sicuramente utile impostare il valore su 2. Se si sta eseguendo un inserto multilinea di grandi dimensioni, non farà molto (se non altro) per Aiuto.

Poiché stai girando il registro binario per questo inserto iniziale, non dovresti preoccuparti degli spazi nei numeri di incremento automatico (se esegui inserimenti simultanei).


La ringrazio per la risposta! L'inserto in blocco sembra così veloce e lo proverò più tardi.
inohiro,

Basta impostare autocommit = 0 aumentato sebbene messo da ordini di grandezza. Grazie!
Alex Barker,

1

È possibile utilizzare i seguenti metodi per accelerare gli inserti:

  • Se si inseriscono più righe dallo stesso client contemporaneamente, utilizzare le INSERTistruzioni con più VALUESelenchi per inserire più righe contemporaneamente. Ciò è notevolmente più veloce (molte volte più veloce in alcuni casi) rispetto all'uso di INSERTistruzioni separate a riga singola . Se si aggiungono dati a una tabella non vuota, è possibile ottimizzare la variabile bulk_insert_buffer_size per rendere l'inserimento dei dati ancora più veloce.
  • Quando si carica una tabella da un file di testo, utilizzare LOAD DATA INFILE. Questo di solito è 20 volte più veloce rispetto all'uso delle INSERTistruzioni. Vedere
  • Approfitta del fatto che le colonne hanno valori predefiniti. Inserisci i valori esplicitamente solo quando il valore da inserire differisce dal valore predefinito. Ciò riduce l'analisi che deve eseguire MySQL e migliora la velocità di inserimento.
  • Vedere la Sezione 9.5.5, " Caricamento di dati in blocco per le tabelle InnoDB " per suggerimenti specifici sulle tabelle InnoDB.

0

Piano A: INSERTI "Batch": più righe per istruzione INSERT. Suggerisci circa 1000 righe per istruzione. autocommit = on, nessun esplicito BEGIN ... COMMIT

Piano B: CARICO DATI

Se si inseriscono troppe righe contemporaneamente, InnoDB deve fare più lavoro per poter ripristinare l'inserimento in caso di arresto anomalo. Per questo motivo, non sono d'accordo con autocommit = off, che metterebbe l'intero set in un'unica transazione.

I DATI DI CARICO dell'intero set di righe potrebbero avere lo stesso problema, ma è abbastanza veloce.

buffer_pool = 5G su 6G è sul punto di essere troppo grande. In caso di scambio, le prestazioni crolleranno.

Il partizionamento probabilmente lo farebbe rallentare.

MOSTRA CREA TABELLA - Le chiavi secondarie potrebbero essere un grave handicap.

Stai usando InnoDB? o XtraDB?


La ringrazio per la risposta. Sto usando InnoDB. Preferisco il piano A al piano B. LOAD DATAsembra così veloce, ma dobbiamo scrivere i dati sul testo immediatamente come CSV, quindi usare LOAD DATAgiusto? / Imposterò il valore buffer_pool_sizesu 4 GB.
inohiro,
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.