2015-12-16 494 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' 
相關問題