使用多个子查询加快mysql查询速度

时间:2011-04-12 11:39:31

标签: mysql optimization subquery

我想知道是否有办法加快多个子查询排序的mysql查询。

在音乐相关网站上,用户可以喜欢不同的东西,如艺术家,歌曲,专辑等。这些“喜欢”都存储在同一个表格中。现在我想显示一个由用户朋友和所有用户按“喜欢”的数量排序的艺术家列表。我想展示所有艺术家,也包括那些根本没有喜欢的人。

我有以下查询:

SELECT `artists`.*, 

    // friend likes
    (SELECT COUNT(*)
     FROM `likes`
     WHERE like_type = 'artist'
     AND like_id = artists.id
     AND user_id IN (1,2,3,4, etc) // ids of friends
     GROUP BY like_id
    ) AS `friend_likes`, 

    // all likes
    (SELECT COUNT(*)
     FROM `likes`
     WHERE like_type = 'artist'
     AND like_id = artists.id
     GROUP BY like_id
    ) AS `all_likes`

FROM artists
ORDER BY 
    friend_likes DESC, 
    all_likes DESC, 
    artists.name ASC

对于具有2000行的艺术家表格,查询需要±1.5秒。随着桌子变得越来越大,我担心这会花费更长的时间。我尝试使用JOINS似乎无法使其工作,因为子查询包含WHERE语句。

非常感谢任何正确方向的想法!

3 个答案:

答案 0 :(得分:3)

尝试使用JOIN而不是子查询:

SELECT
  artists.*, -- do you really need all this?
  count(user_id) AS all_likes,
  sum(user_id IN (1, 2, 3, 4)) AS friend_likes
FROM artists a
LEFT JOIN likes l
  ON l.like_type = 'artist' AND l.like_id = a.id
GROUP BY a.id
ORDER BY 
  friend_likes DESC, 
  all_likes DESC, 
  artists.name ASC;

如果这不能使查询更快,请尝试添加索引,或考虑选择更少的字段。

答案 1 :(得分:0)

你需要稍微分解一下,看看时间在哪里。你绝对正确,2000行1.5秒不能很好地扩展。我怀疑你需要看看索引和外键关系。分别查看每个计数/分组查询,以便最好地进行调整,然后重新组合。

答案 2 :(得分:0)

尝试使用内联IF()进行查询并浏览表/ join ONCE

SELECT STRAIGHT_JOIN
  artists.*
  , LikeCounts.AllCount
  , LikeCounts.FriendLikeCount
FROM  
  (SELECT
    like_id
    , count(*) AllCount
    , sum( If( User_id in ( 1, 2, 3, 4 ), 1, 0 ) as FriendLikeCount
  FROM
    friend_likes
  WHERE
    like_type = 'artist'
  GROUP BY 
    like_id ) LikeCounts
JOIN artists ON LikeCounts.like_id = artists.id
ORDER BY
  LikeCounts.FriendLikeCount DESC
  , LikeCounts.AllCount DESC
  , artists.name ASC