2016-05-16 13 views
5

Sto cercando di capire perché una query è così lenta sul mio database MySQL. Ho letto vari contenuti sulle prestazioni di MySQL, varie domande su SO, ma questo rimane un indovinello per me.Query molto lenta sulla tabella mysql con 35 milioni di righe

  1. Sto usando MySQL 5.6.23-log - MySQL Community Server (GPL)
  2. Ho una tabella con circa 35 milioni di righe.
  3. Questa tabella viene inserito per circa 5 volte/secondo
  4. La tabella si presenta così: enter image description here

  5. ho indici su tutte le colonne ad eccezione di answer_text

La query Sono in esecuzione è:

SELECT answer_id, COUNT(1) 
FROM answers_onsite a 
WHERE a.screen_id=384 
AND a.timestamp BETWEEN 1462670000000 AND 1463374800000 
GROUP BY a.answer_id 

questa query tak es circa 20-30 secondi, poi dà un set di risultati:

enter image description here

Eventuali approfondimenti?

EDIT

come richiesto, il mio spettacolo create table:

CREATE TABLE 'answers_onsite' (
    'id' bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    'device_id' bigint(20) unsigned NOT NULL, 
    'survey_id' bigint(20) unsigned NOT NULL, 
    'answer_set_group' varchar(255) NOT NULL, 
    'timestamp' bigint(20) unsigned NOT NULL, 
    'screen_id' bigint(20) unsigned NOT NULL, 
    'answer_id' bigint(20) unsigned NOT NULL DEFAULT '0', 
    'answer_text' text, 
    PRIMARY KEY ('id'), 
    KEY 'device_id' ('device_id'), 
    KEY 'survey_id' ('survey_id'), 
    KEY 'answer_set_group' ('answer_set_group'), 
    KEY 'timestamp' ('timestamp'), 
    KEY 'screen_id' ('screen_id'), 
    KEY 'answer_id' ('answer_id') 
) ENGINE=InnoDB AUTO_INCREMENT=35716605 DEFAULT CHARSET=utf8 
+1

Pls aggiunge l'output di spiegazione della query e elenca tutti gli indici presenti sulla tabella. Probabilmente non hai un indice multi colonna che velocizzerebbe la query. – Shadow

+3

Le schermate sono in genere un modo terribile di mostrare queste informazioni. Puoi sostituirlo con il contenuto testuale di 'SHOW CREATE TABLE' per quella tabella? – tadman

+0

ha aggiornato la mia domanda, incollato l'istruzione della tabella di creazione. Inoltre, gli indici sono ben spiegati lì – ThaiKov

risposta

3
ALTER TABLE answers_onsite ADD key complex_index (screen_id,`timestamp`,answer_id); 
1

è possibile utilizzare mysql Partitioning come questo:

alter table answers_onsite drop primary key; 
alter table answers_onsite add primary key (id, timestamp) partition by HASH(id) partitions 500; 

Esecuzione quanto sopra può prendere una mentre a seconda delle dimensioni del tuo tavolo.

0

Guardate il vostro clausola WHERE:

WHERE a.screen_id=384 AND a.timestamp BETWEEN 1462670000000 AND 1463374800000 GROUP BY a.answer_id

vorrei creare un indice composito (screen_id, answer_id, timestamp) ed eseguire alcuni test. Si potrebbe anche provare (screen_id, timestamp, answer_id) per vedere se funziona meglio.

La clausola BETWEEN è nota per essere lenta, come qualsiasi query di intervallo. Quindi è COUNT su milioni di righe. Contarei una volta al giorno e salvare il risultato in una tabella "Statistiche" che puoi richiedere quando ti serve ... ovviamente se non hai bisogno di dati live.