MySQL索引建议

时间:2018-07-13 18:01:30

标签: mysql indexing

select distinct g4_airport.id              as g4airportidentifier,
            airport.id                 as airportidentifier,
            airport.iata_code          as airportiata,
            airport.ident              as airporticao,
            airport.local_code         as airportfaa,
            airport.lastupdated        as lastupdated,
            g4_airport.last_updated    as lastupdatedg4,
            airport.name               as airportname,
            airport.municipality       as cityname,
            airport.latitude           as latitude,
            airport.longitude          as longitude,
            airport.region_iso         as regioniso,
            airport.country_iso        as countryiso,
            airport.timezone           as timezonename,
            g4_airport.is_fuel         as isfuel,
            g4_airport.use_tsa_scanner as isscanner,
            g4_airport.is_station      as isstation,
            g4_airport.is_charter      as ischarter,
            g4_airport.min_connection  as minconnectiontime,
            g4_airport.max_connection  as maxconnectiontime,
            g4_airport.min_turn        as minturn,
            g4_airport.rp_turn         as rpturn,
            g4_airport.acars_active    as isacarsactive,
            g4_airport.code_type       as codetype
from   airports.g4_airport
   join airports.airport
     on g4_airport.code = case g4_airport.code_type
                            when 'iata' then airport.iata_code
                            when 'faa' then airport.local_code
                            when 'icao' then airport.ident
                          end
where  airport.country_iso = 'us'
order  by airport.iata_code;

我遇到了这样的情况,即查询试图运行11秒,而我试图在所有提到的情况下创建索引以防万一和联接。 mysql仍然没有选择索引。请提供帮助和建议。

2 个答案:

答案 0 :(得分:0)

MySQL无法将索引用于联接。

您可以对三个联接使用联合(对于iata,faa和icao每个联接)。

答案 1 :(得分:0)

关注...

SELECT  ...
    from  g4_airport AS g4
    join     airport AS a
         ON g4.code = case g4.code_type
             when 'iata' then a.iata_code
             when 'faa'  then a.local_code
             when 'icao' then a.ident   end
    where  a.country_iso = 'us'
    order by  a.iata_code;

请尝试这些,并提供EXPLAIN SELECT ...和时间。

抛弃DISTINCT,我认为这不是必需的,至少在我的《思想2,3》中不需要。

思想#1: INDEX(country_iso, iata_code)

思想#2:

( SELECT  ...
    from  g4_airport AS g4
    join     airport AS a
         ON g4.code_type = 'iata'
        AND g4.code = a.iata_code
    where  a.country_iso = 'us'
    order by  a.iata_code;
) UNION ALL
( SELECT  ...
    from  g4_airport AS g4
    join     airport AS a
         ON g4.code_type = 'faa'
        AND g4.code = a.local_code
    where  a.country_iso = 'us'
)
) UNION ALL
( SELECT  ...
    ...  icao...ident
)    
ORDER BY  a.iata_code;

airport:     INDEX(country_iso)   -- although it may not be used
g4_airport:  INDEX(code_type, code)  -- for each `JOIN`

思想#3:

首先获取ID,然后查找详细信息

SELECT a..., g4...        -- the various columns desired
    FROM
    (      -- start of UNION
        ( SELECT  a.id AS aid, g4.id AS g4id   -- only the PKs
            from  g4_airport AS g4
            join     airport AS a
                 ON g4.code_type = 'iata'
                AND g4.code = a.iata_code
            where  a.country_iso = 'us'
            order by  a.iata_code;
        ) UNION ALL
        ( SELECT  a.id AS aid, g4.id AS g4id
            from  g4_airport AS g4
            join     airport AS a
                 ON g4.code_type = 'faa'
                AND g4.code = a.local_code
            where  a.country_iso = 'us'
        )
        ) UNION ALL
        ( SELECT  ...
            ...  icao...ident
        )
    ) AS u       -- end of the UNION
    JOIN    airport AS a  WHERE  a.id = u.aid
    JOIN ga_airport AS g4 WHERE g4.id = u.g4id
    ORDER BY  u.iata_code;

airport:     INDEX(country_iso)   -- although it may not be used
g4_airport:  INDEX(code_type, code)  -- for each `JOIN`

(如果每个表,我都假设idPRIMARY KEY。)

我不知道第3个想法会比第2个更快。

(想法#2,3的表可能会倒退。)