背景
我正在爲自定義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