我有一个大的mysql表('d_operations'),有超过200万条记录(还有更多记录)。我写了一个PHP网页,显示一个图表,其中包含每半小时一天的操作次数(0:00 0:30 1:00 1:30 ... 23:59)。 它工作得很好,但需要花费太多时间才能得到结果,所以我想知道我的表和查询是否可以优化。
每天半小时我会做一个选择查询,询问MySQL在那段时间内完成的操作次数。 这需要一分多钟才能完成!
这是表架构:
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是UNIX时间戳
这是我在PHP中进行查询的方式:
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];
}
在最糟糕的情况下,我在那一天每半小时循环一次,即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)
有更有效的方法吗? (表定义,MySQL查询优化......)
由于
答案 0 :(得分:0)
正如Jon Stirling和Mark Baker所说,解决方案就像为tstamp列创建索引一样简单:
ALTER TABLE d_operations ADD INDEX ts_index(tstamp);
谢谢!