MySQL estremamente lento su query SELECT molto semplici


10

Abbiamo una semplice applicazione Web in esecuzione su una macchina virtuale che salva i suoi dati in un database MySQL 5.5 con il motore InnoDB. Tutto ha funzionato bene per circa tre anni, ma improvvisamente è diventato estremamente lento.

Ad esempio, ho una tabella molto semplice con indirizzi:

CREATE TABLE `addresses` (
  `address_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) CHARACTER SET latin1 NOT NULL,
  `firstname` varchar(64) CHARACTER SET latin1 NOT NULL,
  `street` varchar(64) CHARACTER SET latin1 NOT NULL,
  `housenumber` varchar(16) CHARACTER SET latin1 NOT NULL,
  `zip` varchar(5) CHARACTER SET latin1 NOT NULL,
  `city` varchar(64) CHARACTER SET latin1 NOT NULL,
  `email` varchar(64) CHARACTER SET latin1 NOT NULL,
  `phone` varchar(16) CHARACTER SET latin1 NOT NULL,
  `birthdate` date NOT NULL,
  PRIMARY KEY (`address_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

Questa tabella contiene circa 800 voci, il che in realtà non è molto. Ma eseguendo la query

SELECT * FROM addresses

a scopo di test, sembra non finire mai. L'ho verificato con l'interfaccia della riga di comando mysql sul server stesso: restituisce alcune righe della tabella e quindi attende molto a lungo fino a quando non restituisce le righe successive.

Quindi forse è un problema nella fase di invio dei dati, ma non ne sono sicuro.

La VM ha 2 GB di RAM e vengono utilizzati solo 320 MB. La CPU funziona anche con un minimo dell'1-2%. mytop non mostra altre query che bloccano il server. L'amministratore IT ha affermato di non aver cambiato nulla dal lato hardware.

Ho già provato qualcosa come riavviare il server di database, riavviare la macchina virtuale. Niente ha aiutato.

modificare:

EXPLAIN SELECT * FROM addresses

mi dà questo risultato:

+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | addresses | ALL  | NULL          | NULL | NULL    | NULL |  793 |       |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

Virtual Box, Xen o qualcos'altro? Come è impostato il disco host? ci sono anche altre macchine virtuali nella stessa scatola che funzionano lentamente? Rispondere a queste domande potrebbe rivelare la risposta
Matt,

Non sono il proprietario dell'hypervisor, quindi non posso davvero rispondere a questa domanda. Ho già chiesto all'amministratore dell'hypervisor se sono a conoscenza di eventuali modifiche recenti, ma ha detto di no.
tab

se puoi, spegni mysql ed esegui alcuni benchmark su disco e memoria. Non deve essere complicato. L'idea è quella di isolare solo se si tratta di un problema con mysql, forse indice problema come indicato nella risposta di seguito, o più diffuso.
Matt,

Bene, l'ho sperimentato probabilmente per non essere un problema mysql. L'esecuzione mysql -u username -ppassword mydb -e 'SELECT * FROM addressesè molto lenta, ma aggiungendo `> test.txt`, funziona molto velocemente. Ora questa sarebbe probabilmente una domanda diversa !? Come potrei indagare su questo?
tab

Contattare il proprietario dell'hypervisor e chiedere loro di verificare la presenza di errori nei registri. In particolare errori del disco. Digli i tuoi sintomi. Esegui il backup ora.
Matt,

Risposte:


13

Se il carico della cpu è basso, ciò indica che non ci sono problemi con gli indici mancanti, in tal caso la query dovrebbe richiedere solo più cpu e accesso al disco. Inoltre hai detto che ha funzionato bene per 3 anni.

Hai controllato la velocità generale di accesso al disco (in particolare sulla partizione in cui si trova il database)? Ad esempio usando dd come qui . Quello che stai descrivendo suona come un disco morto o un raid mezzo morto. Hai dei backup, spero?


È un buon punto. Potrebbe essere qualcosa di semplice come un errore del disco sull'host.
Matt,

9

Puoi provare un paio di cose,

  1. Hai impostato gli indici?

L'indicizzazione consente di trovare rapidamente i record senza eseguire prima una scansione completa della tabella, riducendo drasticamente i tempi di esecuzione.

CREATE INDEX idx_name ON addresses(name);
  1. Prima di eseguire la query, utilizzare prima la parola chiave EXPLAIN,

Se usato davanti a una query SELECT, descriverà come MySQL intende eseguire la query e il numero di righe che dovrà elaborare prima che termini.

  1. Apporta alcune modifiche a mysql.ini, se è una macchina virtuale aumenta la RAM e configura mysql.ini per vedere se le prestazioni aumentano.

Ci sono molti ottimizzatori MySQL là fuori che possono guidarti.

Aiuta questo aiuta


Va bene, ma la creazione di un indice su una tabella piuttosto piccola (<800 righe) sembra non essere così utile come avrei bisogno. Ci vuole più di un minuto per completare la query sopra citata. Una scansione completa di un tavolo così piccolo non dovrebbe richiedere così tanto tempo.
tab

Quindi ... hai aggiunto gli indici? Se non sei sicuro di quale sia il problema, vorrei iniziare di base e scendere fino in fondo. L'aggiunta di indici aumenterà le prestazioni solo se eseguita correttamente.
Anthony Fornito,

Sì, ho aggiunto un indice sulla colonna del nome. Ma la mia query sopra non ha nemmeno alcuna clausola WHERE restrittiva, quindi dovrà leggere l'intera tabella e stamparla. Aggiunto l'indice non ha aiutato.
tab

Ho aggiunto il risultato della query EXPLAIN sopra. Questo mi sembra perfetto, ma le prestazioni sono ancora molto basse. Non riesco ad aumentare la RAM in quanto non sono l'amministratore del gestore della virtualizzazione. Ma htopmostra che vengono utilizzati solo 307 MB su 2050 MB di RAM.
tab

A proposito degli indici devi davvero pensare a quali colonne indicizzare, non vuoi semplicemente indicizzare tutto, indicizzare quelli che hanno la maggior quantità, sto facendo alcune ipotesi selvagge su questo, ma inizierei con name'firstname'. Secondo, sei sicuro di aver eseguito correttamente l'indicizzazione? possible_keys: NULL se la colonna è NULL, indica che non è stato trovato alcun indice rilevante.
Anthony Fornito,
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.