2015-12-16 2 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 db используется –

+0

@EnriqueQuero Это myISAM – cleverketchup

+0

Каковы типы данных двух столбцов itc_route.adep и Airport.icao? Может быть, они разные типы, и база данных выполняет неявный тип для каждого набора данных? – Olli

ответ

1

Если больше, скажем, 20% строк в этом диапазоне дат, тогда оптимизатор решит, что быстрее просто выполнить сканирование таблицы. Примечание. Это не обязательно медленная часть задачи.

После получения этих строк, он должен искать в другой таблице. Это может быть медленной частью.

Вы используете MyISAM. (Вы должны рассмотреть возможность перехода на InnoDB.) Если key_buffer_size слишком мал, в этом кеше может произойти переполнение. Это значение должно быть около 20% от доступно ОЗУ.

Похоже, у вас есть индекс «префикс»? Name(8). Не делай этого; это больно производительности.

Airport необходим сводный указатель: INDEX(icao, IATA).

EXPLAIN и определения таблиц не согласуются. Предоставьте SHOW CREATE TABLE; он более четкий и более полный, чем изображения, которые вы предоставили.

1

Использование innodb Если вы этого не используете. Создайте индекс нескольких столбцов (icao, IATA) в airport_copy, с помощью которого вы можете воспользоваться индексом покрытия. Теперь попробуйте выполнить следующий запрос. Если не работает нормально, тогда разместите свое объяснение здесь.

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' 
Смежные вопросы