2015-12-16 402 views
1

我有一个查询,它花费太长时间来执行(约5分钟):简单的MySQL的加入需要很长时间来执行

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.180s执行

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

任何想法?

+0

您需要所有属性?什么是mysql数据库引擎正在使用 –

+0

@EnriqueQuero它是myISAM – cleverketchup

+0

两列itc_route.adep和Airport.icao的数据类型是什么?也许它们是不同的类型,数据库为每个数据集执行隐式类型转换? – Olli

回答

1

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

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

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

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

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

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

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' 
相关问题