Enormi differenze di prestazioni di MySQL in due server


8

Abbiamo un server MySQL installato su due macchine diverse, un server di test e un server di produzione, entrambi Windows, che viene utilizzato da un'applicazione Web.

Il problema è che ci sono enormi differenze di prestazioni tra le due macchine quando si eseguono alcune query (il server di produzione è quello più lento). La versione di MySQL in entrambi i server è la stessa, anche i file di configurazione sono gli stessi (l'unica differenza è il percorso dei dati e il fatto che il server di produzione non registra nient'altro che gli errori). La differenza di prestazioni di cui sto parlando è maggiore di 3 o 4 ordini di grandezza (ad es. Una query nel server di test viene eseguita in 0,2 secondi, mentre nel server di produzione viene eseguita in 84 secondi).

Le query offensive fanno ampio uso delle clausole con "WHERE [...] IN [...]", che è mia comprensione che di solito sono molto lente e dovrebbero essere sostituite con JOIN. Tuttavia, la versione di MySQL che stiamo usando è 5.6.19, che ottimizza automaticamente quelle query, ecco perché si comportano velocemente nel server di test (e sono in una parte del programma che non possiamo cambiare, quindi non possiamo ottimizzarle manualmente Comunque).

Come ho detto, l'installazione e la configurazione di MySQL sono identiche, quindi non ho idea di dove possa essere il problema. Da un lato, ho il sospetto che debba trattarsi di un problema di configurazione in qualche modo dato che il programma e il DB sono gli stessi, d'altra parte, questo non ha senso poiché la configurazione è identica.

Alcuni dati sui server:
server di prova:

  • Intel Core 2 Quad Q9400 a 2,66 GHz
  • 8 GB di RAM
  • Standard di Windows Server 2008 R2

Server di produzione:

  • Intel Xeon E5530 @ 2.40GHz
  • 5 GB di RAM
  • Standard di Windows Server 2012 R2

Modifica: ho dimenticato di dire una cosa importante: ci sono più query in esecuzione che usano le clausole "WHERE ... IN" a parte quelle "offensive". Vengono eseguiti rapidamente in entrambe le macchine, il che mi suggerisce che sono stati correttamente ottimizzati da MySQL. Il fatto che alcune query siano ottimizzate quando altre non lo sono è un mistero per me, SE questo è il vero problema, di cui non sono sicuro.

Modifica n. 2: ecco il file di configurazione per entrambi i server: http://pastebin.ca/2834906

Modifica n. 3: Ecco l'esempio di una delle query lente: https://mariadb.org/ea/v36zj EXPLAIN è esattamente lo stesso sia in test che in prod. La query stessa è qui: http://pastebin.com/VXgBxXmt È stata formattata con un autoformatter, quindi forse non è molto chiara. Come puoi vedere, è piuttosto lungo e complesso. Non è stato generato manualmente, sono generati automaticamente dal software, che utilizza un dialetto dell'SQL standard con alcune funzioni.

Inoltre, ulteriori informazioni: abbiamo risolto temporaneamente il problema riducendo i dati nel server di produzione e rimuovendo la maggior parte dei vecchi dati nel DB, che non verrà utilizzato. Questa non è una soluzione, ovviamente, poiché abbiamo bisogno anche dei vecchi dati e sarà un problema in futuro. Il DB non è così grande: il DB completo è di 1308 MB, la versione ridotta attualmente in produzione è di 332 MB.

AGGIORNAMENTO: RISOLTO ??

Penso di aver risolto il problema. Non l'ho ancora testato, dal momento che il server di produzione viene effettivamente utilizzato, ma il possibile problema era il parametro "innodb_buffer_pool_size", che era impostato su 182M. In realtà, la riga nel file di configurazione mostra: innodb_buffer_pool_size = 321 che è un errore poiché non ha il prefisso dell'unità, dando un valore non valido (il minimo è 5242880 secondo i documenti), quindi mettendolo al valore precedente . Questo valore nel server di test è stato impostato sul 321M desiderato.

Come ho detto, non l'ho provato completamente. Quello che ho fatto è stato ridurre il valore nei test e provare l'applicazione. Tutto procede più lentamente e la query particolare che ho pubblicato viene eseguita in 3 minuti.

Ho messo alla prova un valore più sano di 3Gb, che non so se sia una buona idea, quindi se qualcuno ha qualche commento su questo valore, lo apprezzerò.

Le mie conclusioni, il "valore sano" di 3Gb e le informazioni che ho usato per questo provengono da questi due post, in particolare il secondo:

Query MySQL, 2 server simili, 2 minuti di differenza nei tempi di esecuzione

Quanto dovrebbe essere grande mysql innodb_buffer_pool_size?

Pubblicherò i risultati "reali" quando aggiorneremo i valori nel server di produzione.

Grazie a tutti.

RISOLTO

Quindi, alla fine abbiamo provato questo in prod, ed era il problema che ho commentato in precedenza. Ho messo il valore di innodb_buffer_pool_size in 321M, che è il valore raccomandato dal fornitore dell'SDK che usiamo, anche se secondo i collegamenti precedenti dovrebbe essere di circa 3G per un DB di queste dimensioni e utilizzo.

Tuttavia, ho ancora dei dubbi: il valore di 321 era un valore non valido (troppo piccolo), quindi MySQL ha preso un altro valore. Il mio sospetto è che ci siano voluti il ​​precedente numero valido, 321 M in prova e 182 M in prod, quindi le differenze di velocità. È solo per curiosità, ma vorrei sapere se questo è giusto.

Grazie ancora a tutti per l'aiuto.


1
I database hanno le stesse dimensioni su ciascun server? Un database di test più piccolo verrà eseguito più velocemente di un database di produzione più grande. Inoltre, il server di test ha quasi il doppio della RAM. Com'è l'utilizzo della memoria?

1
Sì, i DB sono gli stessi (in realtà un dump del DB di produzione nel DB di test). Non ho ancora verificato l'utilizzo della memoria nel server di produzione, lo farò ora e informerò.

1
Potresti estrarre le stesse statistiche RAM dalla casella di test? Vedi se sembrano significativamente diversi?
Chris S,

2
Puoi pubblicare un esempio di una query che funziona alla grande in TEST ma è orribile in PROD? Inoltre, esegui il piano EXPLAIN sulla query in entrambi i sistemi e pubblica i risultati.
RolandoMySQLDBA il

3
@juantxorena: devi scartare le ragioni, e non supporre nulla , da facili a difficili da controllare. Motivo del passaggio 1: differenze nel piano di query. Esegui EXPLAIN sulla produzione e sullo sviluppo, controlla le differenze (anche se minime). Aggiungi tali informazioni e quindi possiamo andare al passaggio 2.
jynus

Risposte:


4

Potrei essere cieco su questo, ma qui va ...

Nella tua domanda e nei tuoi commenti, hai dichiarato quanto segue:

La versione di MySQL in entrambi i server è la stessa, anche i file di configurazione sono gli stessi (l'unica differenza è il percorso dei dati e il fatto che il server di produzione non registra altro che gli errori)

Sì, i DB sono gli stessi (in realtà un dump del DB di produzione nel DB di test).

Risultati simili: 2,31 Gb in modo stabile

È necessario fornire il piano EXPLAIN per una query. Poiché i dati sono identici, potrebbe non essere necessario.

Ci sono un paio di cose che potrebbero essere diverse

IL TUO PROCESSORE

Ho cercato Intel Core 2 Quad Q9400 a 2,66 GHz (TEST) e Intel Xeon E5530 a 2,40 GHz (PROD) e ho trovato una differenza.

  • CPU per TEST ha 4 thread
  • La CPU per PROD ha 8 thread

Penseresti che PROD dovrebbe essere più veloce.

La velocità del bus interno potrebbe essere il collo di bottiglia. Sospetto questo perché TEST ha una velocità del bus più alta e un moltiplicatore del bus di 8. Che cos'è un moltiplicatore del bus ?

La frequenza interna dei microprocessori si basa generalmente sulla frequenza del bus del lato anteriore. Per calcolare la frequenza interna, la CPU moltiplica la frequenza del bus per un determinato numero, che si chiama moltiplicatore di clock. È importante notare che per il calcolo la CPU utilizza la frequenza effettiva del bus e non la frequenza effettiva del bus. Per determinare la frequenza effettiva effettiva del bus per i processori che utilizzano bus a doppia velocità dei dati (AMD Athlon e Duron) e bus a velocità quad-data (tutti i microprocessori Intel a partire da Pentium 4), la velocità effettiva del bus deve essere divisa per 2 per AMD o 4 per Intel.

Sulla base di questo, la velocità del bus interno per AMD (TEST) è almeno 2 volte più di Intel (PROD).

LE TUE STATISTICHE DELL'INDICE

Poiché hai caricato TEST con gli stessi dati, una cosa potrebbe essere stata trascurata. Sto pensando alle statistiche dell'indice. Per TEST, le statistiche dell'indice sarebbero abbastanza nuove. Per PROD, potrebbe essere obsoleto se nelle tabelle indicizzate sono stati rilevati numerosi INSERT, UPDATE e DELETE.

L'esecuzione di un SELECT su due macchine diverse con identica versione mysql, configurazioni mysql identiche, set di dati identici e persino hardware identico, potrebbe essere influenzata dalle statistiche dell'indice sulla tabella interessata.

Avrei eseguito ANALYZE TABLE su tutte le tabelle su PROD e TEST e quindi avrei provato a confrontare le prestazioni.


Grazie per la tua risposta approfondita. Ho eseguito la TABELLA ANALISI su tutte le tabelle e i tempi di esecuzione sono simili. PROD è un po 'più lento nella maggior parte dei casi, un po' più veloce in altri, ma sto parlando di millisecondi, quindi non penso che sia la causa. Sto ancora cercando.
juantxorena,
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.