Ho una semplice tabella con milioni di record (14.000.000) e per una semplice query sta impiegando troppo tempo a "inviare dati".
La tavola
CREATE TABLE IF NOT EXISTS details (
id int(11) NOT NULL,
date date NOT NULL,
time int(2) NOT NULL,
minutes_online decimal(5,0) NOT NULL,
minutes_playing decimal(5,0) NOT NULL,
minutes_chatting decimal(5,0) NOT NULL,
minutes_away decimal(5,0) NOT NULL
PRIMARY KEY (id,date,time)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
La semplice domanda
mysql> SELECT * FROM details WHERE id = 3014595;
Spiegare
mysql> EXPLAIN SELECT * FROM details WHERE id = 3014595;
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | details | ref | PRIMARY | PRIMARY | 4 | const | 1482 | |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
Profilo per la query
mysql> SHOW PROFILE FOR QUERY 1;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000024 |
| checking query cache for query | 0.000078 |
| checking permissions | 0.000014 |
| Opening tables | 0.000126 |
| System lock | 0.000011 |
| Table lock | 0.000030 |
| init | 0.000027 |
| optimizing | 0.000117 |
| statistics | 0.040077 |
| preparing | 0.000029 |
| executing | 0.000006 |
| Sending data | 7.536960 |
| end | 0.000013 |
| query end | 0.000004 |
| freeing items | 0.000037 |
| storing result in query cache | 0.000006 |
| logging slow query | 0.000003 |
| cleaning up | 0.000006 |
+--------------------------------+----------+
Come puoi vedere, l' SELECT
istruzione usa l'indice e legge solo 1482 righe. Tuttavia, la query ha impiegato 7,536960 secondi per l'invio dei dati. È come se la query leggesse molte più righe necessarie.
È una query semplice, con solo 7 campi (riga avg 59 byte) e nessuna funzione elaborata. Qualche idea di cosa possa causare questo?
Nota: id è l'ID utente. Ogni utente può avere almeno una voce per ogni ora di ogni giorno. Pertanto, id non è unico.
Modifica: ho un'altra tabella con la stessa struttura e molte più righe (34 milioni). Se eseguo la stessa query su questa tabella più grande, restituisce i risultati in meno di 1 secondo.
L'unica differenza è che la tabella più grande non riceve tutte le query della tabella più piccola.
- È possibile che il numero di query stia rallentando il processo? La cache di MySQL è attiva. Ho anche CakePHP memorizzato nella cache le query per ridurre il numero di query.
- È possibile che il file in cui viene salvata la tabella sia danneggiato o qualcosa del genere?
Aggiornamento Il problema è stato risolto separando il livello dati dal livello Web. Il livello dati ha anche un aggiornamento sulla RAM ed è in esecuzione su raid10.
1591 rows in set (16.48 sec)
Ho eseguito nuovamente la query, ecco perché la durata è diversa. Ci sono voluti 16 secondi (!!)
SELECT
restituisce?