EXPLAINまたはEXPLAINEXTENDED はいつでも使用できます MySqlがクエリで何をしているのかを確認する
少し違う方法でクエリを書くこともできますが、次のことを試しましたか?
SELECT s.*,
sm.url AS media_url
FROM shows AS s
INNER JOIN show_medias AS sm ON s.id = SM.show_id
WHERE `s`.`id` IN (
SELECT DISTINCT st.show_id
FROM show_time_schedules AS sts
LEFT JOIN show_times AS st ON st.id = sts.show_time_id
WHERE sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date)
)
AND `s`.`is_active` = 1
AND sm.is_primary = 1
ORDER BY s.name asc
その効果が何であるかを見るのは興味深いでしょう。現時点では、MySqlはショーごとに内部クエリ1を実行すると思います(1つのクエリが何度も実行されるように、結合の方が効率的です)。
show_mediasに行がないすべてのショーが必要な場合は、INNERJOINをLEFTJOINに置き換えます。
編集:
間もなく拡張されたEXPLAINを見ていきます。また、次のことを試してみませんか。すべてのサブクエリが削除されます:
SELECT DISTINCT s.*,
sm.url AS media_url
FROM shows AS s
INNER JOIN show_medias AS sm ON s.id = SM.show_id
INNER JOIN show_times AS st ON (s.id = st.show_id)
RIGHT JOIN show_time_schedules AS sts ON (st.id = sts.show_time_id)
WHERE `s`.`is_active` = 1
AND sm.is_primary = 1
AND sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date)
ORDER BY s.name asc
(これらについて説明が拡張されているのを見るのも良いでしょう-これのコメントに追加することができます)
さらに編集:
EXPLAIN EXTENDED(これらの読み方の良いスタートここにあります )
USINGFILESORTとUSINGTEMPORARYはどちらも重要な指標です。うまくいけば、私がお勧めする2番目のクエリでは、(サブクエリ内の)TEMPORARYテーブルをすべて削除する必要があります。次に、ORDER BYをオフのままにして、違いが生じるかどうかを確認します(これまでの調査結果に追加できます:-)
また、多くのインデックスルックアップでクエリが欠落している可能性があることもわかります。すべてのid列は、インデックス一致の主要な候補です(通常のインデックスの警告 )。また、これらのインデックスを追加してから、EXPLAIN EXTENDEDを再度実行して、現在の違いを確認します(上記のコメントからすでにわかっているように、編集してください)