2012-01-26 4 views
0

私は以下のDBスキームを持っています: scheme of my DB テーブル "e_tram"には何千もの "cars"があります。 各車には、テーブル "e_vozy_typy"に車の種類に関する情報を持つレコードを追加できます。テーブル "e_vozy_dopravci"には所有者に関する情報があり、 "e_vozy_razeni"と "e_vozy_evc"には車の登録などに関する情報があります "poradi"列には最新のレコードの最大値と最も古いレコードの最小値があります(最小値は通常1)。JOINで従属クエリを使用したクエリが遅い

私は、各車のために他のテーブルからの最新の情報を返す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 

このクエリは、約90秒かかり、すべての列番号(+外部キー・カラム)とporadi上のインデックスのにもかかわらず。私は、MySQLがJOINの従属クエリでインデックスを使用しないことをEXPLAINで見ることができます。これを効果的に行う方法はありますか?

答えて

0

データに問題はありませんが、パフォーマンスを向上させてリンク可能なインデックスを提供するには、データベースを非正規化する必要があります。 e_tramテーブルで、参加する各子テーブルのmax_fieldカラムを追加し、それらのフィールドをどのように埋めるかを決めます。メインクエリが実行される前に、各フィールドの更新を実行するか、子テーブルが変更されたときに特定のフィールドを更新するトリガーを実行できます。