Siempre puede usar EXPLAIN o EXPLAIN EXTENDED para ver qué está haciendo MySql con una consulta
También podría escribir su consulta de una manera ligeramente diferente, ¿ha intentado lo siguiente?
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
Sería interesante ver cuál es el efecto de eso. Espero que sea más rápido ya que, en este momento, creo que MySql ejecutará la consulta interna 1 para cada programa que tenga (de modo que una consulta se ejecutará muchas veces. Una combinación debería ser más eficiente).
Reemplaza INNER JOIN con LEFT JOIN si quieres todos los programas que no tienen una fila en show_medias.
EDITAR:
Echaré un vistazo a su EXPLICACIÓN EXTENDIDA en breve, también me pregunto si desea probar lo siguiente; elimina todas las subconsultas:
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
(También sería bueno ver EXPLICACIÓN EXTENDIDA en estos; podría agregarlo a los comentarios para este).
EDICIÓN adicional:
En su EXPLAIN EXTENDED (un buen comienzo sobre cómo leer estos está aquí )
USING FILESORT y USING TEMPORARY son indicadores clave. Con suerte, la segunda consulta que recomiendo debería eliminar las tablas TEMPORALES (en la subconsulta). Intente luego dejar ORDER BY desactivado para ver si eso hace la diferencia (y podemos agregar eso a los hallazgos hasta ahora :-)
También puedo ver que la consulta potencialmente está perdiendo muchas búsquedas de índice; todas sus columnas de identificación son candidatas principales para las coincidencias de índice (con el habitual advertencias sobre los índices ). También intentaría agregar esos índices y luego ejecutar EXPLAIN EXTENDED nuevamente para ver cuál es la diferencia ahora (¡EDITAR como ya sabemos por su comentario anterior!)