背景
我正在为自定义Web应用程序构建一个简单的聊天客户端。我需要存储所有聊天记录。用户也可以向个人或群组发送消息。认为谷歌聊天(我告诉我的客户使用,而不是他坚持自定义)。我的数据库的构建方式:如何优化聊天室查询?
表:聊天室
int主键ChatRoomID
VARCHAR(64)名称表ChatMessage
int主键ChatMessageID
int 用户ID
INT ChatRoomID
VARCHAR(2000)消息
日期时间日期表ChatUser
INT ChatRoomID
INT 用户ID
INT LastMessageID 主键(ChatRoomID,用户名)
我使用SQL服务器等解决方案需要在两个平台上工作,将尽快迁移到MySQL。
我的问题
假设一个用户刚刚登录我需要拉的所有聊天室与优秀的邮件列表。我当前的查询看起来是这样的:
SELECT DISTINCT
cr.ChatRoomID AS id,
cu.LastMessageID AS label
FROM ChatRooms cr
LEFT JOIN ChatUsers cu ON cu.ChatRoomID = cr.ChatRoomID
LEFT JOIN ChatMessages cm ON cm.ChatRoomID = cr.ChatRoomID
WHERE cu.UserID = :user_id
AND cu.LastMessageID < cm.ChatMessageID
问题
这似乎是工作相当出色。不过,我怀疑当他们有几十个用户,数千个房间和数百万条消息时,这会变得效率低下。如何优化此查询(或数据库结构)以使此请求(具有针对给定用户的未解决消息的聊天室的数量)成为性能可伸缩的查询?
我主要关心的是我不得不为这个查询使用“distinct”标志。所以这可能会加入一个临时表的数百万,然后过滤到2个数字。
实施例数据
用户
1 | A医生
2 | B医生
3 | Biller A
4 | Biller B
5 |老板ChatRoom
1 | Doctor Group
2 |账单组ChatUser
客房|用户|消息
- | - | -------
1 | 1 | 0
1 | 2 | 2
1 | 5 | 2
2 | 3 | 6
2 | 4 | 0
2 | 5 | 5聊天消息
ID |房间|用户|消息
- | - | - | -------
1 | 1 | 5 | “今天每个人怎么样?”
2 | 1 | 2 | “我很好,在5号房间需要更多的乐队帮助。”
3 | 2 | 5 | “有人可以用Band Aids补充房间5吗?”
4 | 2 | 3 | “这不是我的工作得到一个走狗。”
5 | 2 | 5 | “无论如何,或者你被解雇了。”
6 | 2 | 3 | “这不是你,我放弃了。”
在这种情况下用户1和4是上班迟到了,当他们登录的消息会弹出,以及用户5是在他的计费部门下一次的惊喜我运行查询。
你能提供一些测试数据给我们测试和理解可扩展性方面 – TheGameiswar
和实际ddl包括索引。 –
我不知道ddl是什么,索引应该非常明显。我确实添加了一个示例场景。 – danielson317