SELECT DISTINCT(journey.id), line.name, journey.departure
FROM journey
INNER JOIN journey_day ON journey_day.journey = journey.id
INNER JOIN service ON service.id = journey.service
INNER JOIN operator ON operator.id = service.operator
INNER JOIN line ON line.service = service.id
INNER JOIN pattern ON pattern.id = journey.pattern
INNER JOIN pattern_link pl ON pl.section = pattern.section AND pl.from_stop = "370023292"
INNER JOIN pattern_link pl2 ON pl2.section = pattern.section AND pl2.from_sequence < pl.from_sequence
WHERE journey_day.day = 1 AND CURDATE() BETWEEN service.date_start and service.date_end AND operator.id = "TMTL"
ORDER BY journey.departure
Выше представлен запрос MySQL, выполнение которого занимает приблизительно 0,05 секунды.
Как только я добавляю этот LEFT JOIN journey_code ON journey_code.journey = journey.id
, он добавляет к запросу еще 4-6 секунд. Я считаю, что это как-то связано со второй ссылкой на столбец journey.id
в предложении ON
. Почему это LEFT JOIN
так сильно задерживает результаты запроса?
Информация о таблице journey_code
:
id(INT 11 PK AI) | journey(VARCHAR 128) | code(VARCHAR 16)
И journey
, и code
имеют индексы. Я пробовал составной индекс для двух, и это никоим образом не ускорило запрос.
Результат добавления EXPLAIN
к запросу: http://i.imgur.com/BVrm9qv .png
Есть идеи, почему это происходит?
1 ответ
Попробуйте превратить указанный выше запрос в подзапрос:
SELECT j.*, jc.<whatever>
FROM (SELECT DISTINCT journey.id, line.name, journey.departure
FROM journey
INNER JOIN journey_day ON journey_day.journey = journey.id
INNER JOIN service ON service.id = journey.service
INNER JOIN operator ON operator.id = service.operator
INNER JOIN line ON line.service = service.id
INNER JOIN pattern ON pattern.id = journey.pattern
INNER JOIN pattern_link pl ON pl.section = pattern.section AND pl.from_stop = "370023292"
INNER JOIN pattern_link pl2 ON pl2.section = pattern.section AND pl2.from_sequence < pl.from_sequence
WHERE journey_day.day = 1 AND
CURDATE() BETWEEN service.date_start and service.date_end AND
operator.id = 'TMTL'
) j left join
journey_code jc
ON jc.journey = j.id
ORDER BY j.departure
Как работает MySQL, он должен запустить подзапрос и материализовать его. Если у вас есть индекс по journey_code(journey)
, соединение должно быть быстрым.
Похожие вопросы
Новые вопросы
mysql
MySQL — это бесплатная система управления реляционными базами данных (RDBMS) с открытым исходным кодом, которая использует язык структурированных запросов (SQL). НЕ ИСПОЛЬЗУЙТЕ этот тег для других БД, таких как SQL Server, SQLite и т. д. Это разные БД, которые используют свои собственные диалекты SQL для управления данными. В вопросе всегда указывайте точную версию сервера. Версии 5.x сильно отличаются по своим возможностям от версий 8+.
EXPLAIN