私は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のクエリの最適化...)
おかげで
'tstamp'にはインデックスが必要です。 –
あなたが探している最適化は「インデックス作成」と呼ばれます –
私はかなり新しいMySQLです。つまり、次のことを意味します:ALTER TABLE d_operations ADD INDEX ts_index(tstamp); ? –