假设我们有以下场景,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存储每个用户的更新列表或社交订阅源条目,但在搜索方案中,这样的东西似乎不足。没有?
非常感谢任何有关讨论类似问题和方法的资源的建议,提示或链接!
答案 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最短路径。