mysql impiega troppo tempo per inviare i dati


9

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' SELECTistruzione 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.


Quante righe SELECTrestituisce?
hjpotter92,

1591 rows in set (16.48 sec)Ho eseguito nuovamente la query, ecco perché la durata è diversa. Ci sono voluti 16 secondi (!!)
rlcabral

invece di usare * prova ad usare le colonne e poi vedi che differenza fa
Muhammad Raheel

No. Stesso risultato
rlcabral,

Prova a rendere la colonna ID un semplice indice primario. Poiché l'ID deve essere un campo univoco, non è necessario creare indici complessi con esso. Questo dovrebbe rendere la tua ricerca per chiave primaria veloce come una velocità della luce.
Alexander Pravdin,

Risposte:


1

Per chiunque si imbattesse in questa domanda e si chiedesse, anche senza l'aggiornamento della RAM, perché l'invio dei dati richiedesse molto più tempo. È perché l'invio dei dati include effettivamente il tempo di ricerca dei dati che devono essere inviati.

https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html

Il thread sta leggendo ed elaborando le righe per un'istruzione SELECT e inviando i dati al client. Poiché le operazioni che si verificano durante questo stato tendono ad eseguire grandi quantità di accesso al disco (letture), è spesso lo stato più lungo durante la vita di una determinata query.


-2

Prova a ottimizzare la tabella utilizzando Ottimizza tablename tabella e controlla lo stato.

Grandi cambiamenti devono essere fatti:

Alter table tablename engine = 'INNODB'

Questo ti aiuterà molto e probabilmente ci dovrebbe essere una chiave primaria nella tabella ma hai aggiunto tre colonne come chiave primaria.


-3

Crea un indice separato per l'id:

modifica dettagli tabella aggiungi chiave d1 (id);

Per rendere effettivo questo indice, riavvia MySQL o

analizzare i dettagli della tabella;

Se possibile, è anche possibile modificare il database in InnoDB per il supporto delle transazioni e altri vantaggi.


Come sarà d'aiuto?
Colin 't Hart,
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.