SELECT COUNT(*)
FROM song AS s
JOIN user AS u
ON(u.user_id = s.user_id)
WHERE s.is_active = 1 AND s.public = 1
s.active和s.public是索引以及u.user_id和s.user_id。
歌曲表行数310k
用户表行数22k
有没有办法优化这个?我们在这上面得到1秒的查询时间。
答案 0 :(得分:3)
确保歌曲上有复合“覆盖”索引:(user_id, is_active, public)
。在这里,我们将索引命名为covering_index
:
SELECT COUNT(s.user_id)
FROM song s FORCE INDEX (covering_index)
JOIN user u
ON u.user_id = s.user_id
WHERE s.is_active = 1 AND s.public = 1
在这里,我们确保使用覆盖索引而不是主键来完成JOIN,这样覆盖索引也可以用于WHERE子句。
我还将COUNT(*)
更改为COUNT(s.user_id)
。虽然MySQL应该足够聪明,可以从索引中选择列,但为了以防万一,我明确地命名了列。
确保在服务器上配置了足够的内存,以便所有索引都可以保留在内存中。
如果您仍然遇到问题,请发布EXPLAIN
。
答案 1 :(得分:0)
也许将其写为存储过程或视图...您也可以先尝试选择所有ID,然后在结果上运行计数...如果您将所有ID作为一个查询执行,则可能会更快。通常,优化是通过使用嵌套选择或使服务器完成工作来完成的,因此在我可以想到的所有上下文中。
SELECT Count(*) FROM
(SELECT song.user_id FROM
(SELECT * FROM song WHERE song.is_active = 1 AND song.public = 1) as t
JOIN user AS u
ON(t.user_id = u.user_id))
还要确保使用正确的联接方式。