2013-06-01 52 views
1

我有一個使用子查詢的簡單查詢:使用JOINS,而不是子查詢

SELECT pictures.* 
FROM pictures 
WHERE pictures.user_id IN 
    (SELECT follows.following_id 
    FROM follows 
    WHERE follows.follower_id = 9) 
ORDER BY created_at DESC LIMIT 5; 

我很納悶, 一)如何刪除子查詢和使用JOINS,而不是和b)會不會有使用JOINS而不是子查詢的性能好處?

(follows.following_id,follows.follower_id,pictures.user_id都編入索引)

感謝

+2

爲什麼你要刪除的子選擇?使用連接的查詢返回的內容與子選擇完全不同,您需要使用例如'distinct',就像JW的答案一樣,通過子選擇將JOIN的結果減少到查詢的結果。我懷疑這會更快。 –

+0

[子選擇明確表示您想要表達的內容](http://stackoverflow.com/a/2577188/237483)。要回答b),你必須用你的數據集來測試兩個版本。 –

+1

@a_horse_with_no_name我從jw的答案中使用了INNER JOIN。它給我0.5 - 1毫秒的結果,而子查詢給我的結果在4.5 - 7.5毫秒之間。 – 0xSina

回答

4
SELECT DISTINCT pictures.* 
FROM pictures 
     INNER JOIN follows 
      ON pictures.user_ID = follows.following_id 
WHERE follows.follower_id = 9 
ORDER BY pictures.created_at DESC 
LIMIT 5 

爲了進一步獲得更多的知識有關加入,請訪問以下鏈接:

UPDATE

另一種方式來達到同樣的效果是通過使用EXISTS

SELECT * 
FROM pictures 
WHERE EXISTS 
     (
      SELECT 1 
      FROM follows 
      WHERE pictures.user_ID = follows.following_id AND 
        follows.follower_id = 9 
     ) 
ORDER BY pictures.created_at DESC 
LIMIT 5 
+0

謝謝!爲什麼INNER JOIN?爲什麼不能左外連接? – 0xSina

+1

'LEFT JOIN'將返回表'picture'中的所有記錄,所有不匹配的記錄將在'follow'表上的列上具有'null'值。但是因爲你已經根據表'columns'中的列進行了過濾,所以'INNER JOIN'中的結果是相同的,因爲它只會返回與條件匹配的記錄。刪除NULL記錄。嘗試執行'LEFT JOIN',你會得到相同的結果。 –

+0

我更新了使用'EXISTS'的答案。 –