Du kan altid bruge EXPLAIN eller EXPLAIN UDVIDET for at se, hvad MySql laver med en forespørgsel
Du kan også skrive din forespørgsel på en lidt anden måde. Har du prøvet følgende?
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
Det ville være interessant at se, hvad effekten af det er. Jeg ville forvente, at det var hurtigere, da jeg i øjeblikket tror, at MySql vil køre indre forespørgsel 1 for hvert show, du har (så en forespørgsel vil blive kørt mange gange. En joinforbindelse burde være mere effektiv).
Erstat INNER JOIN med en LEFT JOIN, hvis du vil have alle shows, der ikke har en række i show_medias.
EDIT:
Jeg vil snart tage et kig på din EXPLAIN UDVIDET, jeg spekulerer også på, om du vil prøve følgende; det fjerner alle underforespørgsler:
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
(Det ville også være godt at se EXPLAIN UDVIDET på disse - du kan tilføje det til kommentarerne til denne).
Yderligere EDIT:
På din EXPLAIN EXTENDED (en god start på, hvordan du læser disse er her )
USING FILESORT og USING TEMPORARY er begge nøgleindikatorer. Forhåbentlig bør den anden forespørgsel, jeg anbefaler, fjerne alle MIDLERTIDIGE tabeller (i underforespørgslen). Prøv så at lade ORDER BY være slået fra for at se, om det gør en forskel (og vi kan tilføje det til resultaterne indtil videre :-)
Jeg kan også se, at forespørgslen potentielt går glip af en masse indeksopslag; alle dine id-kolonner er primære kandidater til indeksmatches (med den sædvanlige indeksforbehold ). Jeg ville også prøve at tilføje disse indekser og derefter køre EXPLAIN EXTENDED igen for at se, hvad forskellen er nu (EDIT, som vi allerede ved fra din kommentar ovenfor!)