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.