2014-09-25 71 views
0

下面的查询:MySQL查询不使用索引

EXPLAIN 
SELECT 
    fdb . * , 
    TIME_FORMAT(fdb.scheme, '%H:%i') AS scheme, 
    TIME_FORMAT(fdb.actual, '%H:%i') AS actual, 
    TIME_FORMAT(fdb.baggage, '%H:%i') AS baggage, 
    TIME_FORMAT(fdb.baggage_handled, '%H:%i') AS baggage_handled, 
    ff . * , TIME_FORMAT(ff.actual_saved, '%H:%i') AS actual_saved, 
    TIME_FORMAT(ff.baggage_saved, '%H:%i') AS baggage_saved, 
    TIME_FORMAT(ff.baggage_handled_saved, '%H:%i') AS baggage_handled_saved, 
    ap.device_id, 
    ap.device_token, 
    ap.device_language, 
    ap.app_edition, 
    ap.receive_status_notifications, 
    ap.receive_time_notifications, 
    ap.receive_luggage_notifications, 
    ap.receive_gate_notifications, 
    ap.receive_runway_notifications, 
    ap.receive_plane_notifications 
FROM flights_database fdb 
    JOIN flights_followed ff ON fdb.flight_id = ff.flight_id 
    JOIN apns_users ap ON ff.device_id = ap.device_id 
         AND ap.app_edition = '1' 

使用说明后,很明显的查询使用表扫描: enter image description here

有各种按键和pusher_idx同时包含device_idflight_id 。为什么这个索引不被使用?

+0

我认为索引只能用作索引,当你只引用索引字段。如果您从同一个表中加入非索引字段,则会进行扫描。也期望函数调用将索引分解为扫描。 – Pieter21 2014-09-25 22:03:50

+0

'SHOW CREATE TABLE \'apns_users \';','SHOW CREATE TABLE \\ flights_followed \';' – Sebas 2014-09-25 22:22:46

回答

0

在这种情况下,MySQL优化改变了你的表的顺序(它可以做到这一点 - 他们都是INNER JOINS):

SELECT 
    ... 
FROM flights_followed ff 
    JOIN flights_database fdb ON fdb.flight_id = ff.flight_id 
    JOIN apns_users ap ON ff.device_id = ap.device_id 
         AND ap.app_edition = '1' 

因此,一旦flights_followed不受任何自己的谓词过滤(用新加盟为了加入其他表格,加入了其他表格,因此它们被过滤) - 它决定执行全面扫描。

+0

所以我没办法解决这个问题? – edwardmp 2014-09-26 00:28:40

+0

@edwardmp:解决“什么”?您请求完整扫描 - mysql执行它。如果你不想要一个完整的扫描 - 为'ff'添加一些谓词到'WHERE'(或相关的'ON') – zerkms 2014-09-26 01:07:03

+0

我误解了。谢谢。在ff上添加一个WHERE仍然使用表扫描:( – edwardmp 2014-09-26 15:31:40