2011-08-10 26 views
0

我在使用MYSQL進行IN查詢時遇到問題。如何提高我的子查詢的性能?

基本上我建立一個朋友圖,當用戶〜< 5個朋友,它減緩抓取

然而

與高朋(7000+)的用戶 - 它運行速度更快的超級。

這裏是我的實體模型查詢:

SELECT * 
FROM activity 
WHERE user_id IN 
(
    SELECT friend_id 
    FROM friends 
    WHERE user_id = 1 and approved = 1 
) 
order by activity.created_at DESC 
LIMIT 25 

出於某種原因,如果USER_ID有< 5位朋友,查詢需要15秒返回0項。

在朋友表上,我有一個關於user_id的索引並被批准。在活動條目上,我有一個關於created_at的索引。

任何建議或重新分解?

+0

這是一個子查詢 - http://dev.mysql.com/doc/refman/5.0/en/optimizing-subqueries.html – ajreal

回答

0

這會

SELECT * FROM activity t1 join friends t2 where t1.user_id=t2.friends_id and t2.user_id=1 and t2.approved=1 order by activity.created_at DESC LIMIT 25

完成相同。它更快嗎?

我想你需要一個關於friend_id,user_id,爲好友表而批准的索引。

0
Select * 
FROM activity a 
JOIN (Select * from friends WHERE user_id = 1 and approved = 1) f 
ON a.user_id = f.friend_id 
ORDER BY a.created_at DESC 
LIMIT 25 

基本上,IN's有點不可預知,我喜歡儘可能使用JOIN。

+0

這適用於小型用戶,但對於高級朋友(> 7000)它很慢。有什麼建議麼? – gregavola

1

基本上在你的例子中,子查詢會每從activity表中選擇每一行執行,您可以通過activity臺移動過濾器外範圍縮小了,所以儘量讓你的頂級查詢到在更具體過濾條款。

試用INNER JOIN,它工作更快嗎?

SELECT * FROM activity a 
INNER JOIN friends f ON a.user_id = f.friend_id 
WHERE a.user_id = 1 AND f.approved = 1 
order by activity.created_at DESC LIMIT 25 

幾個問題:

  • 兩個表有一個user_id列?
  • 覈准在朋友表中的列?
+0

它應該是'... WHERE f.user_id = 1 ...'或不是? +1雖然 查詢應該拉你的朋友的最後25個活動,我想。 –

+0

這兩個表都具有user_Id並且已批准在朋友表中。 – gregavola

+0

運行上面的查詢(使用f.user_id)=是6s。解釋顯示朋友是第一張桌子和第二個活動,並且 - 在哪裏使用;使用臨時;使用filesort – gregavola

0
SELECT a.* FROM activity a, friends f 
WHERE 
      a.user_id = f.friend_id 
    AND f.user_id = 1 
    AND f.approved = 1 
ORDER BY activity.created_at DESC 
LIMIT 25 

對每一個指標:a.user_idf.friend_idf.user_id

請勿索引f.approved,因爲它很可能是低基數列。