2014-10-13 58 views
1

我有兩個表,客戶端將通過使用用戶名搜索用戶表中的記錄和用戶ID,然後搜索房間表並返回結果,但是我現在的代碼似乎很慢。從一個表中選擇數據並加入另一個表爲主「密鑰」是非常緩慢的

我在我的房間表中有大約750,000條記錄,在我的用戶表中有大約550,000條記錄,所以我的結果往往需要大約5-7秒的時間才能顯示回客戶端,是否有替代我的代碼?

SELECT 
    `rooms`.`id`, 
    `rooms`.`caption`, 
    `rooms`.`description`, 
    `rooms`.`roomtype`, 
    `rooms`.`owner`, 
    `rooms`.`state`, 
    `rooms`.`category`, 
    `rooms`.`users_now`, 
    `rooms`.`users_max`, 
    `rooms`.`model_name`, 
    `rooms`.`score`, 
    `rooms`.`allow_pets`, 
    `rooms`.`allow_pets_eat`, 
    `rooms`.`room_blocking_disabled`, 
    `rooms`.`allow_hidewall`, 
    `rooms`.`password`, 
    `rooms`.`wallpaper`, 
    `rooms`.`floor`, 
    `rooms`.`landscape`, 
    `rooms`.`floorthick`, 
    `rooms`.`wallthick`, 
    `rooms`.`mute_settings`, 
    `rooms`.`kick_settings`, 
    `rooms`.`ban_settings`, 
    `rooms`.`chat_mode`, 
    `rooms`.`chat_speed`, 
    `rooms`.`chat_size`, 
    `rooms`.`trade_settings`, 
    `rooms`.`group_id`, 
    `rooms`.`tags`, 
    `rooms`.`push_enabled`, 
    `rooms`.`pull_enabled`, 
    `rooms`.`enables_enabled`, 
    `rooms`.`respect_notifications_enabled` 
FROM 
    `rooms` 
JOIN `users` ON `users`.`id` = `rooms`.`owner` 
WHERE 
    `users`.`username` = 'query' 
ORDER BY 
    `rooms`.`users_now` DESC 
LIMIT 50 

解釋計劃:

1 SIMPLE users const PRIMARY,id,username username 128 const 1 Using index 
1 SIMPLE rooms index owner users_now 4  50 Using where 

我已經收錄了相應的列,但似乎仍然很慢的結果。謝謝!

+2

如果你在兩個表中有很多列,那麼不要使用'*'只是選擇需要的部分,同時在你的問題中發佈'EXPLAIN你的查詢'計劃以供查詢 –

+0

@M Khalid Junaid對此抱歉,我只是爲了這個帖子(認爲查詢可能在這裏看起來太大/太狹窄了),我已經更新了這篇文章。 – Sledmore

+0

這已經足夠了,您還需要運行[*'Explain' *](http://dev.mysql.com/doc/refman/5.0/en/explain.html)計劃查詢並將輸出內容發佈到您的問題,以便未來的訪問者可以分析原因 –

回答

0

正如我所看到的,您的結果基於用戶表,但應包含來自房間表的數據。您可以通過兩個查詢而不是一個查詢立即獲得結果。首先獲取您的users.id,然後獲取該結果並搜索房間表以尋找匹配的所有者。

select users.id from users where username='search' 

現在使用users.id數組爲您的房間運行一個全新的查詢。對於每個代碼取決於您正在使用的腳本語言。

雖然我承認這會在腳本中付出更多努力,但它肯定會立即提升您的速度。如果你的用戶結果有多個記錄(例如:如果有多個「users.id」記錄返回,這種方法仍然會比較快捷)。如果有多個記錄,可以構造一個數組,看起來像這樣允許單個查詢來獲取所有的房間:

select * from rooms where owner in ('id1','id2','id3') 

另一種方法是:

select * from rooms where owner in (select users.id from users where username='search') 

這種方法比較簡單,似乎便宜,但很好地工作。它不會返回用戶數據,只是房間數據。第一種方法將允許您捕獲第一個查詢中的用戶數據和第二個中的房間數據。

+0

感謝您的意見。從進一步的檢查中,我發現額外的2秒只是從排序。我將在後端進行更改,並使用Linq實時對結果進行排序。 – Sledmore

+0

我強烈建議你研究爲什麼數據庫需要這麼長時間並修復它,以便數據庫以合理的方式進行排序。將數據庫吸入內存並對其進行排序只會導致一個痛苦的世界。 – LoztInSpace

+0

@LoztInSpace的問題似乎是ORDER BY。除了獲取我需要的數據並在腳本中對其進行排序之外,我無法真正想到更好的解決方案。我會留下這個問題再打開一會兒,看看是否有人有任何建議。再次感謝。 – Sledmore

0

你的查詢看起來很好,記錄的數量也不是很高。

確保users.id和rooms.owner都被編入索引。

您是否需要ORDER BY - 如果需要文件夾,這會導致性能問題。有一個few你可以做的事情來提高服務器的性能,如果是這樣的話。

EXPLAIN可能有助於縮小問題範圍。

+1

是的,它似乎是ORDER BY導致額外2.5秒,感謝您的鏈接,我會看看。 – Sledmore

相關問題