Come migliorare le prestazioni di MySQL INSERT e UPDATE?


14

Probabilmente questa domanda può essere posta anche su StackOverflow, ma proverò qui prima ...

Le prestazioni delle istruzioni INSERT e UPDATE nel nostro database sembrano degradare e causare scarse prestazioni nella nostra app Web.

Le tabelle sono InnoDB e l'applicazione utilizza le transazioni. Ci sono delle semplici modifiche che posso fare per accelerare le cose?

Penso che potremmo vedere alcuni problemi di blocco, come posso scoprirlo?


Meglio su dba.stackexchange.com
Pacerier

Risposte:


25
  1. Verifica che hardware e sistema operativo siano configurati e ottimizzati correttamente:

    • Fonte del problema (CPU / IO / Memoria / Uso di scambio). Hai molti IOP? La CPU è caricata? Se hai molti IOP letti probabilmente non hai abbastanza buffer_pool di InnoDB. Se la CPU viene caricata, probabilmente le tue query eseguono scansioni complete delle tabelle invece di utilizzare gli indici corretti.
    • Impostazione disco / RAID / LVM. In alcune configurazioni specifiche, lo striping LVM potrebbe offrire vantaggi nell'eqalizzare il carico del disco (nessun RAID hardware, più LUN collegati)
    • IO scheduler: quando hai un buon controller RAID hardware, probabilmente noop è il migliore. RedHat ha effettuato alcuni test e ha affermato che per Oracle (e altri DB) CFQ è la scelta migliore. Devi eseguire alcuni benchmark (come tpc-c o tpc-e) e scegliere, qual è il migliore per il tuo hardware.
    • File system valido: ext3 non funziona bene in carichi di lavoro specifici del database. Meglio è XFS o OCFS2. Hai bisogno di alcuni parametri di nuovo.
    • Guarda, se il tuo sistema utilizza lo scambio. L'uso di swap peggiora le prestazioni di mysql .
  2. Controlla, se l'istanza di MySQL / InnoDB è ottimizzata correttamente:

    • dimensione del pool di buffer: pagine di dati della cache in memoria
    • innodb_flush_method = O_DIRECT - evita il doppio buffer IO
    • aumentare le dimensioni del file di registro InnoDB: per un carico di lavoro intensivo in scrittura ciò potrebbe migliorare le prestazioni. Ma ricorda: una dimensione del file di registro più grande significa un recupero più lungo. A volte in ore !!!
    • innodb_flush_log_at_trx_commit = 0 o 2 - Se non sei preoccupato per ACID e puoi perdere transazioni per l'ultimo o due secondi.
    • key_buffer_size - molto importante per MyISAM, ma viene utilizzato per le tabelle temporanee del disco.
    • Guarda il tuo STATO INNODB
  3. Analizza il tuo carico di lavoro: intercetta tutte le tue query per rallentare il log ed eseguire mk-query-digest su di esso. Puoi catturare tutte le query usando tcpdump e maatkit
    • Quali query richiedono la maggior parte del tempo del server?
    • Vengono create tabelle temporanee, in particolare tabelle temporanee di grandi dimensioni?
    • Scopri come usare spiega
    • La tua applicazione utilizza le transazioni? Quando si eseguono query con autocommit = 1 (impostazione predefinita su MySQL), ogni query di inserimento / aggiornamento avvia una nuova transazione, che comporta un sovraccarico. Se è possibile, è meglio disabilitare autocommit (nel driver MySQL python l'autocommit è disabilitato di default) ed eseguire manualmente il commit dopo aver effettuato tutte le modifiche.
    • La tua applicazione crea una serie di inserti nella stessa tabella in un ciclo? Load data infileil comando è molto più veloce per serie di inserti.
    • Ricorda: select count(*) from table;è molto più lento per innodb che per myisam.
    • Quali tipi di query INSERT / UPDATE richiedono la maggior parte del tempo del server? Come possono essere ottimizzati?
    • Controlla se il tuo DB ha indici corretti e aggiungili, se necessario.

Nel nostro ambiente c'era una situazione in cui un tipo di query di aggiornamento era lento. Il tempo stimato per terminare il processo batch è stato di 2 giorni !!! Dopo aver analizzato il registro di slowquery, troviamo che questo tipo di query di aggiornamento richiede 4 secondi per essere completato. Query si presentava così: update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zz. Dopo aver convertito la query di aggiornamento per selezionare la query ed eseguito, spiega su quella query selezionata che troviamo che questo tipo di query non utilizza l'indice. Dopo aver creato l'indice corretto, abbiamo ridotto i tempi di esecuzione della query di aggiornamento a millisecondi e l'intero lavoro è terminato in meno di due ore.

Alcuni link utili:


Prima di tutto ciò che controlla gli indici. Gli odori degradanti come "man mano che le tabelle diventano più grandi perché non abbiamo indici".
TomTom

5

Con la configurazione predefinita di innoDB sarai limitato alla velocità con cui puoi scrivere e scaricare le transazioni sul disco. Se riesci a gestire la perdita di un piccolo ACID, sperimenta innodb_flush_log_at_trx_commit. Impostare su 0 per scrivere e scaricare il registro su disco circa ogni secondo. Impostare su 1 (impostazione predefinita) per scrivere e scaricare ad ogni commit. Impostare su 2 per scrivere nel file di registro dopo ogni commit ma svuotare solo una volta al secondo.

Se riesci a gestire la perdita di 1s di transazioni, questo può essere un ottimo modo per migliorare notevolmente le prestazioni di scrittura.

Inoltre, presta attenzione a ciò che stanno facendo i tuoi dischi. RAID 10> RAID 5 per le scritture al costo di un disco aggiuntivo.


1

I problemi di blocco saranno esemplificati dagli stati della connessione in show full processlist;

Leggi la my.cnfdocumentazione e MySQL. Le opzioni di configurazione sono ben documentate.

In generale, vuoi che il più possibile venga elaborato in memoria. Per l'ottimizzazione delle query, ciò significa evitare tabelle temporanee. Corretta applicazione degli indici.

L'ottimizzazione sarà specifica per il motore di database preferito e l'architettura dell'applicazione. Ci sono risorse sostanziali preesistenti per una ricerca su Internet.



0

InnoDB è un motore abbastanza buono. Tuttavia, dipende molto dall'essere "sintonizzato". Una cosa è che se i tuoi inserti non sono in ordine crescente di chiavi primarie, innoDB può richiedere un po 'più di MyISAM. Questo può essere facilmente superato impostando un innodb_buffer_pool_size più alto. Il mio consiglio è di impostarlo al 60-70% della RAM totale. Attualmente sto eseguendo 4 di questi server in produzione, inserendo circa 3,5 milioni di righe al minuto. Hanno già quasi 3 Terabyte. InnoDB doveva essere, a causa degli inserti altamente concorrenti. Esistono altri modi per velocizzare gli inserti. E ne ho confrontati alcuni.


0

Come risolvo i problemi di inserimento e aggiornamento in MySQL nell'applicazione Web semplicemente disabilitando l'auto-commit e il commit delle modifiche una volta in Java. Come suggerito nella documentazione mysql.

Documenti MySQL

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.