我有一个表格,格式如下:
+-------------------+----------------+------+-----+---------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+----------------+------+-----+---------------------+-----------------------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| runtime_id | bigint(20) | NO | MUL | NULL | |
| place_id | bigint(20) | NO | MUL | NULL | |
| amended_timestamp | varchar(50) | YES | | NULL | |
| applicable_at | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| schedule_time | timestamp | NO | MUL | 0000-00-00 00:00:00 | |
| quality_indicator | varchar(10) | NO | | NULL | |
| flow_rate | decimal(15,10) | NO | | NULL | |
+-------------------+----------------+------+-----+---------------------+-----------------------------+
我在schedule_time字段上创建了索引
create index table_index on table(schedule_time asc);
当前表格有2121552+条记录。我不明白的是当我解释时。
explain select runtime_id from table where schedule_time >= now() - INTERVAL 1 DAY;
+----+-------------+----------+-------+------------------------------+------------------------------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+------------------------------+------------------------------+---------+------+-------+-------------+
| 1 | SIMPLE | table | range | table_index | table_index | 4 | NULL | 38088 | Using where |
+----+-------------+----------+-------+------------------------------+------------------------------+---------+------+-------+-------------+
1 row in set (0.00 sec)
上面的索引被使用了,但下面的索引没有被使用。
mysql> explain select runtime_id from table where schedule_time >= now() - INTERVAL 30 DAY;
+----+-------------+----------+------+------------------------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+------------------------------+------+---------+------+---------+-------------+
| 1 | SIMPLE | table | ALL | table_index | NULL | NULL | NULL | 2118107 | Using where |
+----+-------------+----------+------+------------------------------+------+---------+------+---------+-------------+
1 row in set (0.00 sec)
如果有人能指出这里有什么问题,我会非常感激,因为数据每12分钟更新一次,随着时间的推移,查询30天或60天的数据速度会变得非常缓慢。
我计划使用它的最终查询如下:
select avg(flow_rate),c.group from table a ,(select runtime_id from table where schedule_time >= now() - INTERVAL 1 DAY group by schedule_time ) b,place c where a.runtime_id = b.runtime_id and a.place_id = c.id group by c.group;
更新 =====>
根据评论,"between fails too" 也会失败。
mysql> explain select runtime_id from table where schedule_time between '2013-07-17 12:48:00' and '2013-08-17 12:48:00';
+----+-------------+----------+------+------------------------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+------------------------------+------+---------+------+---------+-------------+
| 1 | SIMPLE | table | ALL | table_index | NULL | NULL | NULL | 2118431 | Using where |
+----+-------------+----------+------+------------------------------+------+---------+------+---------+-------------+
1 row in set (0.00 sec)
mysql> explain select runtime_id from table where schedule_time between '2013-08-16 12:48:00' and '2013-08-17 12:48:00';
+----+-------------+----------+-------+------------------------------+------------------------------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+------------------------------+------------------------------+---------+------+-------+-------------+
| 1 | SIMPLE | table | range | table_index | table_index | 4 | NULL | 38770 | Using where |
+----+-------------+----------+-------+------------------------------+------------------------------+---------+------+-------+-------------+
1 row in set (0.00 sec)
更新2 =======>
mysql> select count(*) from table where schedule_time between '2013-08-16 12:48:00' and '2013-08-17 12:48:00';
+----------+
| count(*) |
+----------+
| 19440 |
+----------+
1 row in set (0.01 sec)
mysql> select count(*) from table where schedule_time between '2013-07-17 12:48:00' and '2013-08-17 12:48:00';
+----------+
| count(*) |
+----------+
| 597132 |
+----------+
1 row in set (0.00 sec)
服务器版本:5.5.24-0ubuntu0.12.04.1(Ubuntu)
ANALYZE TABLE my_table
是否会改善情况? - Sylvain LerouxEXPLAIN
在列type
中报告ALL
作为连接类型,那么这确实令人困惑...作为可能的解决方法,你可以尝试:SET @d = now() - INTERVAL 30 DAY; SELECT .... where schedule_time >= @d
- Sylvain Leroux