2013-08-18 80 views
6

我有表作爲MySQL索引的範圍

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

更新=====>

按照也會失敗之間的意見最後的查詢。

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) 

Server版本:5.5.24-0ubuntu0.12.04.1(Ubuntu的)

+0

類似的問題在這裏 - 這個想法是使用'之間'的聲明:http://stackoverflow.com/questions/2041575/mysql-query-records-between-today-and-last-30-days – FreudianSlip

+1

我wasn能夠重現這種行爲(不要試圖這麼做,認爲...)只是一個瘋狂的猜測:運行'ANALYZE TABLE my_table'會改善嗎? –

+0

@SylvainLeroux我跑了ANALYZE TABLE,但是兩者之間和Interval之間的結果相同 –

回答

3

MySQL優化試圖做最快的事情 - 它認爲使用索引需要比進行表掃描所需的時間長或長,它會放棄可用的索引。這就是你看到它在你的例子中做的事情:如果範圍很小(1天),索引將會更快;在範圍很大的情況下,你會碰到更多的表,你可能會直接掃描表(記住,使用索引包括搜索索引,然後從表中獲取索引記錄 - 兩組尋求)。

如果您認爲自己比優化程序更好(它不完美),請使用提示(http://dev.mysql.com/doc/refman/5.5/en/index-hints.html)。