简单的mysql连接执行时间太长

时间:2015-12-16 14:24:19

标签: mysql performance join query-optimization

我有一个查询,执行时间太长(约5分钟):

SELECT
    itc_route.adep,
    itc_route.aircraft_id,
    Airport.IATA
FROM
    itc_route
LEFT JOIN airports_copy AS Airport ON itc_route.adep = Airport.icao
WHERE
    itc_route.date BETWEEN '2014-12-01'
AND '2015-12-01'

这部分需要0.180秒来执行

SELECT * FROM airports_copy

这个花了我0.560s

SELECT * FROM itc_route WHERE itc_route.date BETWEEN '2014-12-01' AND '2015-12-01'

但是当我加入它们时 - 它只需要太长时间了!

所以这里我的itc_route表的索引:itc_route indexes

这是我的Airports_copy索引:airports_copy indexes

这是一个解释性声明:explain statement

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

如果超过20%的行在该日期范围内,那么优化器将决定简单地执行表扫描更快。注意:这不一定是任务的缓慢部分。

获取这些行后,必须在另一个表中查找。 可能是缓慢的部分。

您正在使用MyISAM。 (您应该考虑更改为InnoDB。)如果key_buffer_size太小,可能会在该缓存中发生颠簸。该设置应该是可用 RAM的20%左右。

看起来你有一个“前缀”索引? Name(8)。不要那样做;它伤害了表现。

Airport需要一个综合索引:INDEX(icao, IATA)

EXPLAIN和表定义不一致。请提供SHOW CREATE TABLE;它比你提供的图像更清晰,更完整。

答案 1 :(得分:1)

使用innodb如果您不使用它。 在Airports_copy中的(icao,IATA)上创建一个多列索引,您可以利用它覆盖索引。 现在尝试以下查询。如果不能正常工作,请在此处发布解释。

  SELECT
    itc_route.adep,
    itc_route.aircraft_id,
    intr.IATA
FROM
    itc_route
left JOIN 
(
select IATA,icao from airports_copy
) as intr
on intr.icao =itc_route.adep

WHERE
    itc_route.date between '2014-12-01' AND '2015-12-31'