2013-06-01 53 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'的答案。 –