2016-07-04 4 views
-1

Ich habe eine große MySQL-Tabelle ('d_operations') mit mehr als 2 Millionen Datensätze (und mehr zu kommen). Ich habe eine PHP-Webseite geschrieben, die für jede halbe Stunde ein Diagramm mit der Anzahl der Operationen an einem Tag zeigt (0:00 0:30 1:00 1:30 ... 23:59). Es funktioniert gut, aber dauert zu viel Zeit, um die Ergebnisse zu erhalten, also frage ich mich, ob meine Tabelle und Abfragen optimiert werden könnten.MySQL Tabellenoptimierung, um Abfragen zu beschleunigen

Für jede halbe Stunde an einem Tag mache ich eine Select-Abfrage MySQL nach der Anzahl der Operationen in diesem Zeitraum gefragt. Dies dauert mehr als eine Minute zu beenden!

Dies ist das Tabellenschema:

mysql> describe d_operations; 
+-----------+------------------+------+-----+---------+----------------+ 
| Field  | Type    | Null | Key | Default | Extra   | 
+-----------+------------------+------+-----+---------+----------------+ 
| idx  | int(11) unsigned | NO | PRI | NULL | auto_increment | 
| system_id | int(11)   | YES |  | NULL |    | 
| dev_id | varchar(17)  | YES |  | NULL |    | 
| name  | varchar(17)  | YES |  | NULL |    | 
| nond  | smallint(6)  | YES |  | NULL |    | 
| is_new | smallint(6)  | YES |  | NULL |    | 
| tstamp | int(10) unsigned | YES |  | NULL |    | 
+-----------+------------------+------+-----+---------+----------------+ 

ich einen auto_increment Primärschlüssel habe, die nicht in den Abfragen zu helfen scheint. Der Rest der Felder kann wiederholt werden (ein Gerät kann in diesem Zeitraum mehrere Operationen ausführen und es können Zeilen mit demselben T-Stempel sein). tstamp ist UNIX Zeitpunkt

Dies ist, wie ich die Abfragen in PHP zu tun:

for($i=$GLOBALS['init_hour'];$i<=($GLOBALS['end_hour']-1800);$i+=1800){ 
    $n=$i+1800; 
    $sql="SELECT count(*) as num from d_operations where (tstamp >= $i and tstamp < $n);"; 
    $r=mysqli_query($GLOBALS['con'],$sql); 
    $row = mysqli_fetch_row($r); 
    $values = ($i == $GLOBALS['init_hour']) ? $row[0] : $values.",".$row[0]; 
    $GLOBALS['a_average'][$i]=$row[0]; 
} 

Im schlimmsten Fall, ich Schleife durch jede halbe Stunde an diesem Tag, dass 48 Abfragen ist.

Dies ist die MySQL-Befehl erklären:

mysql> explain select count(*) as num from d_operations where (tstamp >= 1464739200 and tstamp < 1464825599); 
+----+-------------+--------------+------+---------------+------+---------+------+---------+-------------+ 
| id | select_type | table  | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+--------------+------+---------------+------+---------+------+---------+-------------+ 
| 1 | SIMPLE  | d_operations | ALL | NULL   | NULL | NULL | NULL | 2215384 | Using where | 
+----+-------------+--------------+------+---------------+------+---------+------+---------+-------------+ 
1 row in set (0.00 sec) 

Gibt es eine effizientere Art und Weise, dies zu tun? (Tabellendefinition, MySQL Query-Optimierung ...)

Dank

+3

Sie sollten einen Index für "tstamp" haben. –

+1

Die Optimierung, die Sie suchen, heißt "Indizierung" –

+0

Ich bin ziemlich neu in MySQL, meinen Sie: ALTER TABLE d_operations ADD INDEX ts_index (tstamp); ? –

Antwort

0

Als Jon Stirling und Mark Baker vorgeschlagen, war die Lösung so einfach wie ein Index für die tstamp Spalte zu erstellen:

ALTER TABLE d_operations ADD INDEX ts_index(tstamp); 

Dank !

Verwandte Themen