2012-04-19 66 views
0

我試圖運行下面的查詢的MySQL查詢:與上加入(速度問題)的範圍

SELECT formatted_journeys.*, MAX(speed) 
FROM formatted_journeys 
JOIN tracker.g_log 
    ON imeiid = vehicle 
    AND g_logid BETWEEN start_g_log AND end_g_log 
GROUP BY id 

然而,這似乎是極其緩慢。這是該查詢的解釋。

+----+-------------+--------------------+------+-------------------------------+-------+---------+-----------------------------------+------+----------+---------------------------------+ 
| id | select_type | table    | type | possible_keys     | key | key_len | ref        | rows | filtered | Extra       | 
+----+-------------+--------------------+------+-------------------------------+-------+---------+-----------------------------------+------+----------+---------------------------------+ 
| 1 | SIMPLE  | formatted_journeys | ALL | vehicle,start_g_log,end_g_log | NULL | NULL | NULL        | 824 | 100.00 | Using temporary; Using filesort | 
| 1 | SIMPLE  | g_log    | ref | PRIMARY,Dupes     | Dupes | 4  | motrak.formatted_journeys.vehicle | 1985 | 100.00 | Using where      | 
+----+-------------+--------------------+------+-------------------------------+-------+---------+-----------------------------------+------+----------+---------------------------------+ 
2 rows in set, 1 warning (0.02 sec) 

的表格如下所示:

formatted_journeys:

+-----------------+------------------+------+-----+---------+----------------+ 
| Field   | Type    | Null | Key | Default | Extra   | 
+-----------------+------------------+------+-----+---------+----------------+ 
| id    | int(11) unsigned | NO | PRI | NULL | auto_increment | 
| start_g_log  | int(11)   | YES | MUL | NULL |    | 
| end_g_log  | int(11)   | YES | MUL | NULL |    | 
| start_latitude | decimal(18,12) | YES |  | NULL |    | 
| start_longitude | decimal(18,12) | YES |  | NULL |    | 
| end_latitude | decimal(18,12) | YES |  | NULL |    | 
| end_longitude | decimal(18,12) | YES |  | NULL |    | 
| start_location | text    | YES |  | NULL |    | 
| end_location | text    | YES |  | NULL |    | 
| distance  | decimal(10,5) | YES |  | NULL |    | 
| start_date  | datetime   | YES |  | NULL |    | 
| end_date  | datetime   | YES |  | NULL |    | 
| vehicle   | int(11)   | YES | MUL | NULL |    | 
| private   | bit(1)   | NO |  | b'0' |    | 
+-----------------+------------------+------+-----+---------+----------------+ 

指數:

+--------------------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table    | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+--------------------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| formatted_journeys |   0 | PRIMARY  |   1 | id   | A   |   830 |  NULL | NULL |  | BTREE  |   | 
| formatted_journeys |   1 | vehicle  |   1 | vehicle  | A   |   4 |  NULL | NULL | YES | BTREE  |   | 
| formatted_journeys |   1 | start_g_log |   1 | start_g_log | A   |   830 |  NULL | NULL | YES | BTREE  |   | 
| formatted_journeys |   1 | end_g_log |   1 | end_g_log | A   |   830 |  NULL | NULL | YES | BTREE  |   | 
+--------------------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 

tracker.g_log:

+-----------+------------------+------+-----+---------+----------------+ 
| Field  | Type    | Null | Key | Default | Extra   | 
+-----------+------------------+------+-----+---------+----------------+ 
| g_logid | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| imeiid | int(10) unsigned | NO | MUL | NULL |    | 
| latitude | decimal(18,12) | YES |  | NULL |    | 
| longitude | decimal(18,12) | YES |  | NULL |    | 
| speed  | int(4)   | YES | MUL | NULL |    | 
| bearing | int(4)   | YES |  | NULL |    | 
| distance | decimal(10,5) | YES |  | NULL |    | 
| eventcode | int(10)   | YES |  | NULL |    | 
| status | int(10)   | YES |  | NULL |    | 
| date  | datetime   | YES |  | NULL |    | 
+-----------+------------------+------+-----+---------+----------------+ 

指數:

+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| g_log |   0 | PRIMARY |   1 | g_logid  | A   |  31760 |  NULL | NULL |  | BTREE  |   | 
| g_log |   0 | Dupes |   1 | imeiid  | A   |   16 |  NULL | NULL |  | BTREE  |   | 
| g_log |   0 | Dupes |   2 | date  | A   |  31760 |  NULL | NULL | YES | BTREE  |   | 
| g_log |   0 | Dupes |   3 | eventcode | A   |  31760 |  NULL | NULL | YES | BTREE  |   | 
| g_log |   1 | speed |   1 | speed  | A   |   423 |  NULL | NULL | YES | BTREE  |   | 
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 

現在我知道,文件排序是不是一件好事,但我將如何擺脫它?

+0

@Arion:感謝您的編輯,正要去做。 – ridecar2 2012-04-19 09:16:13

+0

沒問題..我看不到你在哪裏問:P – Arion 2012-04-19 09:25:20

+0

如果你在'tracker.g_log'表中有'journey_id'字段,情況可能會好很多。 – newtover 2012-04-19 09:48:57

回答

0

您幾乎不會擺脫Using temporary; Using filesort,但查詢可能會更快。

首先,嘗試重寫查詢爲:

SELECT * 
FROM (
    SELECT id, MAX(speed) as max_speed 
    FROM formatted_journeys 
    JOIN tracker.g_log 
    ON imeiid = vehicle 
     AND g_logid BETWEEN start_g_log AND end_g_log 
    GROUP BY id) as maxspeeds 
JOIN formatted_journeys USING (id); 

然後,您可以嘗試強制查詢使用覆蓋指數,儘管這是不容易的查詢。

首先嚐試:添加複合索引(vehicle, start_g_log, end_g_log),並期待在解釋它是否被使用(你應該看到「使用索引」那裏)

+0

這也不算快。 – ridecar2 2012-04-19 10:09:51

+1

@ ridecar2,那麼你可以嘗試添加一個複合'(imeiid,speed)'並嘗試使用提示強制這兩個索引。如果這不起作用,我個人看不到,這是加速它的一種方法。但我可能沒有足夠的經驗=) – newtover 2012-04-19 10:21:09