如何优化自定义每用户搜索结果

时间:2014-02-01 11:37:24

标签: mysql sql database performance caching

假设我们有以下场景,2个实体;用户,图像。
用户可以喜欢图像,也可以互相关注。 (所以我们有2个关系表,user_likes并跟随谁喜欢什么,谁跟随谁保留)

因此,我们(由用户代表)想要执行搜索以获取我们的朋友喜欢的图像并命名为“cat.jpg”。

在sql中就像是

SElECT DISTINCT(images.id) 
FROM images 
JOIN likes ON likes.image_id = images.id 
JOIN 
  (SELECT follow.following_id 
   FROM follow 
   WHERE follow.follower_id = MY_ID) as following 
 ON following.following_id = likes.user_id 
WHERE images.name = "cat.jpg"
ORDER BY images.date DESC
LIMIT 0, 20

以上查询将返回我们关注的用户所喜欢的图像的20个最新唯一ID,以及名为“cat.jpg”的(图像)。

我的问题是......如何优化此程序?

我想到的第一个想法是缓存,但是如果另一个用户搜索“cat.jpg”,他将获得不同的结果(因为他/她将关注一组不同的用户)。 因此,在这种特定情况下的缓存似乎很昂贵,因为可能存在大量可能的搜索关键字和大量用户跟随用户组合。这是一个可行的解决方案?如果该用户再也不会搜索“cat.jpg”,那么缓存响应只会浪费内存。

一般来说,我看到人们建议使用Redis甚至Memcached存储每个用户的更新列表或社交订阅源条目,但在搜索方案中,这样的东西似乎不足。没有?

非常感谢任何有关讨论类似问题和方法的资源的建议,提示或链接!

2 个答案:

答案 0 :(得分:1)

这是您的查询(使用表别名简化):

SElECT DISTINCT i.id
FROM images i JOIN
     likes l
     ON l.image_id = i.id JOIN 
     (SELECT f.following_id 
      FROM follow f
      WHERE f.follower_id = MY_ID
     ) as f 
    ON f.following_id = l.user_id 
WHERE i.name = 'cat.jpg'
ORDER BY i.date DESC
LIMIT 0, 20;

我们怎样才能让它跑得更快?好吧,首先,不需要子查询:

SElECT DISTINCT i.id
FROM images i JOIN
     likes l
     ON l.image_id = i.id JOIN 
     follow f
     ON f.following_id = l.user_id and
        f.follower_id = MY_ID
WHERE i.name = 'cat.jpg'
ORDER BY i.date DESC
LIMIT 0, 20;

其次,以下索引可能有助于提高性能:

images(name, date);
likes(image_id, user_id);
follow(user_id, follower_id);

答案 1 :(得分:0)

是的,这很容易解决。找到所有组合可能是不可能的。同样的问题是图形问题中的最短路径。或AZ最短路径。