您始终可以使用
EXPLAIN or EXPLAIN EXTENDED查看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(这样一个查询将运行多次.连接应该更有效.)
如果您希望所有在show_medias中没有行的节目,请使用LEFT JOIN替换INNER JOIN.
编辑:
我很快就会看看您的EXPLAIN EXTENDED,我也想知道您是否想要尝试以下内容;它删除所有子查询:
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也很好 – 你可以将它添加到这个评论中).
进一步编辑:
USING FILESORT和USING TEMPORARY都是关键指标.希望我推荐的第二个查询应该删除任何TEMPORARY表(在子查询中).然后尝试关闭ORDER BY以查看是否有所作为(我们可以将其添加到目前为止的调查结果中:-)
我还可以看到查询可能在许多索引查找中丢失;所有id列都是索引匹配的主要候选者(通常为index caveats).我还尝试添加这些索引,然后再次运行EXPLAIN EXTENDED以查看现在有什么区别(正如我们已经从上面的评论中了解到的那样编辑!)