Медленный запрос с зависимыми запросами в JOIN - PullRequest
0 голосов
/ 26 января 2012

У меня следующая схема БД: scheme of my DB В таблице «e_tram» тысячи «машин». Каждый автомобиль может иметь больше записей с информацией о типе автомобиля в таблице "e_vozy_typy". В таблице "e_vozy_dopravci" есть информация о владельце, а в "e_vozy_razeni" и "e_vozy_evc" - информация о регистрации автомобиля и т. Д. В столбце «poradi» указано максимальное значение самой новой записи и минимальное значение самой старой записи (минимальное значение обычно равно 1).

Я хочу написать SELECT, который возвращает для каждой машины новейшую информацию из других таблиц.

Я попробовал следующее:

SELECT
    et.id

    aktevt.ntyp,
    aktevt.typ, 

    akteve.evc,
    akteve.ind,

    aktevr.razeni,

FROM e_tram AS et

INNER JOIN (
    SELECT idvozu, MAX(poradi) AS aktporadi
    FROM e_vozy_typy AS evt
    GROUP BY evt.idvozu
)   AS evt
    ON et.id = evt.idvozu

INNER JOIN e_vozy_typy AS aktevt
    ON et.id = aktevt.idvozu AND evt.aktporadi = aktevt.poradi


INNER JOIN (
    SELECT idvozu, MAX(poradi) AS aktporadi
    FROM e_vozy_dopravci AS evd
    GROUP BY evd.idvozu
)   AS evd
    ON et.id = evd.idvozu

INNER JOIN e_vozy_dopravci AS aktevd
    ON et.id = aktevd.idvozu AND evd.aktporadi = aktevd.poradi


INNER JOIN (
    SELECT idvuzdopravce, MAX(poradi) AS aktporadi
    FROM e_vozy_evca AS eve
    GROUP BY eve.idvuzdopravce
)   AS eve
    ON aktevd.id = eve.idvuzdopravce

INNER JOIN e_vozy_evca AS akteve
    ON aktevd.id = akteve.idvuzdopravce 
        AND eve.aktporadi = akteve.poradi


LEFT JOIN (
    SELECT idvuzdopravce, MAX(poradi) AS aktporadi
    FROM e_vozy_razeni AS evr
    GROUP BY evr.idvuzdopravce
)   AS evr
    ON aktevd.id = evr.idvuzdopravce

LEFT JOIN e_vozy_razeni AS aktevr
    ON aktevd.id = aktevr.idvuzdopravce 
        AND evr.aktporadi = aktevr.poradi


GROUP BY et.id

ORDER BY akteve.evc, akteve.ind, et.id

Несмотря на индексы по всем столбцам id (+ внешний ключ-столбцы) и поради этот запрос занимает около 90 секунд. В EXPLAIN я вижу, что MySQL не использует индексы в зависимых запросах в JOIN. Есть ли решение, чтобы сделать это эффективно?

1 Ответ

0 голосов
/ 26 января 2012

С данными нет проблем, но вам может потребоваться денормализовать базу данных для повышения производительности и предоставления связываемого индекса.В вашей таблице e_tram добавьте столбцы max_field для каждой дочерней таблицы, к которой вы присоединяетесь, затем решите, как вы собираетесь заполнять эти поля.Вы можете либо запустить обновление для каждого поля перед выполнением основного запроса, либо вызвать триггер для обновления определенного поля при изменении дочерней таблицы.

...