2016-07-04 19 views
-1

私は200万以上のレコードを持つ大きなmysqlテーブル( 'd_operations')を持っています。私は30分ごとの1日のオペレーション数を示すグラフ(0:00 0:30 1:00 1:30 ... 23:59)を表示するPHP Webページを作成しました。 これは素晴らしいですが、結果を得るには時間がかかりすぎて、テーブルとクエリを最適化できるかどうか疑問に思っています。クエリを高速化するMySQLテーブルの最適化

1日30分ごとに、その期間に実行された操作の数をMySQLに問い合わせる選択クエリを実行します。 これには1分以上かかります!

これは、テーブルのスキーマです:

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 |    | 
+-----------+------------------+------+-----+---------+----------------+ 

私はクエリで助けていないようですAUTO_INCREMENTプライマリキーを持っています。残りのフィールドは繰り返すことができます(デバイスはその期間内に複数の操作を実行でき、同じtstampを持つ行にすることができます)。 TSTAMPは、この私がPHPでクエリを行う方法であるUNIXタイムスタンプ

です:その日のすべての半分を通じて最悪の場合には

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]; 
} 

、Iループ時間、それは48個のクエリです。

このMySQLは、コマンドを説明している:

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) 

は、これを行うためのより効率的な方法はありますか?

ALTER TABLE d_operations ADD INDEX ts_index(tstamp); 

ありがとう:ジョン・スターリングとマーク・ベイカーが示唆したように(テーブル定義、MySQLのクエリの最適化...)

おかげで

+3

'tstamp'にはインデックスが必要です。 –

+1

あなたが探している最適化は「インデックス作成」と呼ばれます –

+0

私はかなり新しいMySQLです。つまり、次のことを意味します:ALTER TABLE d_operations ADD INDEX ts_index(tstamp); ? –

答えて

0

、解決策は、TSTAMP列のインデックスを作成するのと同じくらい簡単でした!