MySQL JOIN缺少正确的索引,表扫描

时间:2013-03-30 15:40:56

标签: mysql sql database 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 个答案:

答案 0 :(得分: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'

但是,这可能不会影响优化策略。