使用JOIN进行简单MySQL SELECT的查询时间长

时间:2012-02-07 18:04:21

标签: mysql select join

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秒的查询时间。

2 个答案:

答案 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))

还要确保使用正确的联接方式。