2009-07-24 39 views
1

我該如何改進這個查詢? 請點擊這裏告訴我,我所有的選項,我的社交網絡DB只挺大隨着我的mysql數據庫增長,我有什麼選擇

這個查詢花費2.1231秒

SELECT friend_friend.friendid, friend_reg_user.disp_name, friend_reg_user.pic_url, friend_reg_user.online 
FROM friend_friend 
INNER JOIN friend_reg_user ON friend_friend.friendid = friend_reg_user.auto_id 
WHERE userid =1 
AND friend_friend.status =1 
ORDER BY autoid DESC 
LIMIT 59535 , 15 


##################################################################################################################################### 
# id # select_type # table   # type # possible_keys # key  # key_len # ref      # rows # Extra  # 
##################################################################################################################################### 
# 1 # SIMPLE  # friend_friend # ref  # userid  # userid # 5  # const     # 59843 # Using where# 
# 1 # SIMPLE  # friend_reg_user # eq_ref # PRIMARY  # PRIMARY # 4  # friend_friend.friendid # 1  #   # 
##################################################################################################################################### 

我有哪些選項時,此表是說一百萬,或甚至2萬行大?此表是用來確定誰是用戶的朋友

回答

2

我知道一個程序員是誰在他的數據庫工作了800萬點的記錄,它確實沒有改變速度那麼多。這只是創建正確的索引並確保您以有效的方式獲取數據。 (關係的數字ID非常有用)

此外,您的查詢在大多數情況下確實是準系統。沒什麼太花哨。這可能只是您的服務器延遲。

+0

是的,我認爲它已儘可能優化,所有正確的索引和東西,但超過2秒是緩慢的。這是從本地運行的,也許這可能是爲什麼它很慢? – JasonDavis 2009-07-24 11:45:35

+0

800萬條記錄並不是那麼多......試着看看當你達到10億時會發生什麼。 – MarkR 2009-07-26 21:43:16

+0

我可以證明,擁有超過1億5千萬行myisam表的quieries在處理可以高效使用索引的查詢時仍然很快。 – nos 2009-07-26 21:46:18

2

也許我真的不明白你的方案,但你真的需要一個LEFT JOIN?你能不能使用INNER JOIN

(我常常聽到它可能是更好的性能,因爲它返回少行;你的情況,如果你想一個人的朋友,我沒有看到左側的點連接:朋友會「鏈接」,和,因此,必須在「鏈接」表中的條目,否)

此外,請確保您有使用上的字段索引:

    在條件
  • (無論是「裏」或「加入」);在這裏似乎還可以
  • 用於排序; autoid是否有索引?

MySQL在某些應用程序中與真正的大表一起使用,並且如果索引/配置正常,可以非常快地回答;所以,有一些我們應該能夠做到的事情;-)

作爲一個旁註:你前綴幾乎所有字段的名稱的表名稱(因爲字段的名稱中的重複,我想) ;你爲什麼不總是做到這一點?它將使查詢只是有點更容易理解;-)

+0

嗨,實際上時間貼2.1231秒是一個內部JOIN我忘了更新它在這裏左邊加入時間大約是2.4231,所以有一個小小的改進。是的,在所有thye右列上都有索引,並且排序後的autoid是主鍵,因此它不能有索引權限?我的意思是主鍵是一個索引? 我想我已經優化了它的最佳效果,但是整整兩秒很慢我認爲=( – JasonDavis 2009-07-24 11:44:11

+0

ergh,太糟糕了,如果有所有必要的索引:-((並且是的,PK也是一個索引)。步驟將是反規範化(http://en.wikipedia.org/wiki/Denormalization)或Sharding(http://en.wikipedia.org/wiki/Sharding)...但有點讓事情變得更難... – 2009-07-24 18:20:13

1

只要列在WHERE子句中的索引,你應該沒問題。我會生成一套大量的測試數據並運行一些基準測試。

而且,更重要的是,你自己熟悉MySQL's EXPLAIN語法。它將幫助您確定查詢中實際使用了多少行(以及其他內容),並且它是優化查詢和表索引的好工具。

0

你應該找出是什麼導致它變慢。

您的數據庫是否適合內存?如果沒有,得到更多 - 不,真的。不管你怎麼看,光盤都很慢。

如果查詢絕對必須使用光盤(比如你的數據庫僅僅是如此龐大的合理的內存,100G +說),那麼你應該試圖儘量減少它需要IO操作的數量。

實際上這意味着一定量的非規範化(你真的需要一個連接嗎?你是否不能在外部參照表上存儲(複製)所有必要的域?),並明智地使用覆蓋索引。

在InnoDB中(我假設你在這裏使用Innodb),主鍵是集羣的。這意味着使用主鍵的查詢比其他索引執行更少的IO(因爲索引與數據一起存儲在相同的頁面中),因爲它們不需要爲每一行做一個潛在的單獨的IO,而這往往是需要在二級索引上。

的基本原理是:

  1. 使用在非生產環境中生產規格硬件數據的生產水平
  2. 診斷什麼重現問題導致它
  3. 做一個改變,這您認爲可能會修復它
  4. 再次測量,使用相同的生產規格非生產環境來驗證修補程序的性能。
  5. 重複,直到你有足夠的性能來解決問題(安撫你的客戶等)

,如果成功,然後你可以做任何你的正常的檢查程序(如迴歸測試等)將發佈改變。

在某些情況下,更改將需要進行重大數據遷移,因此會令人頭疼(例如需要更改10Tb數據表的架構)。

相關問題