2013-03-30 61 views
0

我有這個簡單的JOIN:MySQL的JOIN缺少適當的索引,表掃描

SELECT my_table1.*, 
     TIME_FORMAT(time1, '%H:%i') AS time1, 
     TIME_FORMAT(time2, '%H:%i') AS time2, 
     TIME_FORMAT(time3, '%H:%i') AS time3, 
     my_table2.*, 
     TIME_FORMAT(time2_saved, '%H:%i') AS time2_saved, 
     TIME_FORMAT(time3_saved, '%H:%i') AS time3_saved, 
     my_table3.device_id, my_table3.device_token, 
     my_table3.device_language, my_table3.app_edition 
    FROM my_table1, my_table2, my_table3 
WHERE my_table1.flight_id = mytable_2.flight_id 
    AND my_table2.device_id = my_table3.device_id AND my_table3.app_edition = '1' 

這似乎是低效的,因爲MySQL的報告。 這個查詢的索引顯然不是最優的。所有的表格都有索引,但我錯過了一些東西。

如果我運行查詢之前EXPLAIN,MySQL的返回如下:

1 
SIMPLE 
my_table2 
ALL 
flight_id,device_id 
NULL 
NULL 
NULL 
356 

1 
SIMPLE 
my_table3 
eq_ref 
device_id 
device_id 
128 
my_databasename.my_table2.device_id 
1 
Using where 

1 
SIMPLE 
my_table1 
ref 
flight_id 
flight_id 
99 
my_databasename.my_table2.flight_id 
1 
Using where 

(如果你喜歡看到一個乾淨的桌子,檢查實際的截圖在這裏:http://oi48.tinypic.com/20kov3d.jpg

正如你所看到的第一行顯示「ALL」類型,這意味着它使用全表掃描。我在這裏失蹤了嗎?

回答

1

首先,您應該學習正確的join語法,並且不要在from子句中使用過時的,

我覺得問題是table3。索引對於查詢不是最佳的。更好的索引是table3(app_edition , device_id)。你可以用這個重新嘗試查詢。

查詢應該寫成:

SELECT my_table1.*, 
     TIME_FORMAT(time1, '%H:%i') AS time1, 
     TIME_FORMAT(time2, '%H:%i') AS time2, 
     TIME_FORMAT(time3, '%H:%i') AS time3, 
     my_table2.*, 
     TIME_FORMAT(time2_saved, '%H:%i') AS time2_saved, 
     TIME_FORMAT(time3_saved, '%H:%i') AS time3_saved, 
     my_table3.device_id, my_table3.device_token, 
     my_table3.device_language, my_table3.app_edition 
    FROM my_table1 join 
     my_table2 
     on my_table1.flight_id = mytable_2.flight_id join 
     my_table3 
     on my_table2.device_id = my_table3.device_id AND my_table3.app_edition = '1' 

然而,這可能不會影響優化策略。

+0

你能幫我一下,在這種情況下適當的JOIN語法是什麼?這個語法已經過時了。 – edwardmp

+0

非常感謝,EXPLAIN現在返回該行的ref類型。再次感謝!!奇怪的是,我添加索引到處都是,但忘記了那張表。 – edwardmp

+0

Hoorayed太早了。我幾乎完全相同的查詢,它不能解決問題:只有最後一個AND是不同的..很奇怪 – edwardmp