这适用于我网站上的朋友模块,用户可以在这里与朋友交朋友。 这些存储在“friends:”表中,发起友谊的人是friendship_inviter,而批准/拒绝结束的人是friendhsip_accepter
SELECT user_id, user_name, user_gender
FROM friends
LEFT JOIN users
ON ( users.user_id = friends.friendship_inviter
OR users.user_id = friends.friendship_accepter)
WHERE (friendship_inviter = '125' OR friendship_accepter = '125')
AND user_id !='125'
AND friendship_level = 1;
这会进行全表扫描,即使表格不大(15,000个用户,3000个友谊),平均需要1-1.5秒。
如何以对服务器不那么重要的方式输出当前朋友列表?
答案 0 :(得分:4)
SELECT user_id, user_name, user_gender
FROM friends
LEFT JOIN users
ON users.user_id = friends.friendship_accepter
WHERE friendship_accepter = '125'
AND user_id !='125'
AND friendship_level = 1
UNION
SELECT user_id, user_name, user_gender
FROM friends
LEFT JOIN users
ON users.user_id = friends.friendship_inviter
WHERE friendship_inviter = '125'
AND user_id !='125'
AND friendship_level = 1;
当然,看起来你没有从“friends”表中选择任何东西,并且你的WHERE子句中有额外的列,所以我实际上会编写INNER JOIN,这相当于LEFT JOIN中的你发布的案例:
SELECT user_id, user_name, user_gender
FROM friends
INNER JOIN users
ON users.user_id = friends.friendship_accepter
WHERE friendship_accepter = '125'
AND user_id !='125'
AND friendship_level = 1
UNION
SELECT user_id, user_name, user_gender
FROM friends
INNER JOIN users
ON users.user_id = friends.friendship_inviter
WHERE friendship_inviter = '125'
AND user_id !='125'
AND friendship_level = 1;
答案 1 :(得分:1)
将索引添加到WHERE子句和JOIN中使用的列/组合。
答案 2 :(得分:1)
部分问题可能是friendship_level基数较低。有时,在低基数列上,查询优化器仍会决定进行表扫描。
在查询中考虑friendship_level条件之前,执行EXPLAIN,并确保其他条件正在执行FIRST。在满足前两个条件后剩余的记录扫描将花费更少的时间。
答案 3 :(得分:0)
确保您已将user_id, friendship_accepter, friendship_inviter and friendship_level
编入索引。
那时候你只发布原始查询时间还是包含输出结果的时间?如果它还包括输出,则它可能不是查询,而是输出。
另一件可能会减慢结果的事情是,如果它是在一个缓慢的网络(即互联网)上。缓慢的时间可能是因为这个而不是因为查询。
答案 4 :(得分:0)
我在我的社交网站上做了一些非常相似的事情,但我的情况有点不同, 我为每个友谊插入2条记录,这允许我向用户显示;
待定的朋友请求 发送好友请求 和确认的朋友
我也没有考虑使用UNION。我目前在好友表中有大约50,000个用户和超过1百万行,这对我来说非常有用