我有一个基于会话的消息系统。 (被视为论坛帖子的消息。类似于gmail。) 表:
convos (PRIMARY cid)
messages (PRIMARY mid)
users (PRIMARY uid)
convos中的每一行都是一个帖子。消息中的每一行都是一个回复,包括它所属的cid。我通过使用该cid抓取x最近的消息来加载对话。我还将用户表加入消息ON uid
。 (每条消息都有发件人的uid。)从users
我得到user_name, avatar
。为了说明,基本查询将如下所示:
SELECT
messages.body,
users.avatar
FROM messages
JOIN users ON (users.uid=messages.uid)
WHERE messages.cid=1
如果同一个用户做了很多回复,我会多次抓住她的头像,这是VARCHAR(头像图片的链接)。为了提高性能,我想只抓取每个avatar
一次。我正在考虑使用GROUP BY
或DISTINCT
我要和罗比C的想法一起去。我有公开聊天,任何用户都可以回复并且回复增长。我将在每页显示20条回复。为了获得这20个回复所需的头像,我这样做:
SELECT
u.avatar
FROM(
SELECT uid,cid
FROM messages
WHERE cid=1234
ORDER BY date DESC LIMIT 20
) AS m
JOIN users AS u ON (u.uid=m.uid)
GROUP BY u.uid
子查询最近的20个回复,使用JOIN
获取用户数据,然后GROUP BY users.uid
剪切重复项。似乎运作良好。
答案 0 :(得分:2)
我认为您正在考虑的子查询不会提高性能。使用uid
获取两个结果集并在代码中匹配它们可能会更容易,更高效。
获取邮件内容的查询:
SELECT
messages.body, messages.uid
FROM messages
WHERE messages.cid=1;
获取头像的查询:
SELECT DISTINCT
users.uid, users.avatar
FROM messages
JOIN users ON (users.uid = messages.uid)
WHERE messages.cid=1;
就查询执行时间而言,与您最初的单个查询相比,我认为您不会看到改进。但是,您可以减少IO和/或网络使用。
如果您发现自己经常收到相同的用户信息,那么考虑将整个用户表缓存在内存中是值得的。
答案 1 :(得分:0)
我认为您可能需要更改工作流程中的内容:
不要将您的头像直接存储在db中,而只存储头像文件的路径。通过这种方式,您不会每次都抓住头像,而只会抓住文件的路径。