我有一个查询,执行时间太长(约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'
但是当我加入它们时 - 它只需要太长时间了!
有什么想法吗?
答案 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'