我是一个老派的MySQL用户,总是更喜欢JOIN而不是子查询。但是现在每个人都用子查询,我讨厌它;我不知道为什么。

我缺乏理论知识来判断是否有任何不同。子查询是否与JOIN一样好,因此没有什么可担心的?


当前回答

MSDN文档SQL Server说

Many Transact-SQL statements that include subqueries can be alternatively formulated as joins. Other questions can be posed only with subqueries. In Transact-SQL, there is usually no performance difference between a statement that includes a subquery and a semantically equivalent version that does not. However, in some cases where existence must be checked, a join yields better performance. Otherwise, the nested query must be processed for each result of the outer query to ensure elimination of duplicates. In such cases, a join approach would yield better results.

所以如果你需要

select * from t1 where exists select * from t2 where t2.parent=t1.id

尝试使用join代替。在其他情况下,这没有什么区别。

我说:为子查询创建函数可以消除混乱的问题,并允许您为子查询实现额外的逻辑。因此,我建议尽可能为子查询创建函数。

代码中的混乱是一个大问题,几十年来业界一直在努力避免它。

其他回答

子查询通常用于将单行作为原子值返回,不过它们也可以用于用IN关键字比较多行之间的值。在SQL语句中几乎任何有意义的地方都允许使用它们,包括目标列表、WHERE子句等等。一个简单的子查询可以用作搜索条件。例如,在一对表之间:

SELECT title 
FROM books 
WHERE author_id = (
    SELECT id 
    FROM authors 
    WHERE last_name = 'Bar' AND first_name = 'Foo'
);

注意,在子查询的结果上使用普通值操作符要求只返回一个字段。如果你想检查一个值是否存在于一组其他值中,请使用in:

SELECT title 
FROM books 
WHERE author_id IN (
    SELECT id FROM authors WHERE last_name ~ '^[A-E]'
);

这显然不同于LEFT-JOIN,你只是想连接表a和表B的东西,即使连接条件在表B中没有找到任何匹配的记录,等等。

如果你只是担心速度,你必须检查你的数据库,写一个好的查询,看看是否有显著的性能差异。

我只是在考虑同样的问题,但我在FROM部分使用子查询。 我需要连接和查询大表,“从”表有2800万条记录,但结果只有128个这样小的结果大数据!我在它上面使用MAX()函数。

首先,我使用LEFT JOIN,因为我认为这是正确的方式,mysql可以优化等。 第二次只是为了测试,我重写了针对JOIN的子选择。

LEFT JOIN运行时:1.12s SUB-SELECT运行时间:0.06秒

子选择比连接快18倍!只是在chokito广告。subselect看起来很糟糕,但结果…

这取决于几个因素,包括正在运行的特定查询、数据库中的数据量。子查询首先运行内部查询,然后从结果集中再次过滤出实际结果。而在join中运行并产生结果。

最好的策略是同时测试连接解决方案和子查询解决方案,以获得优化的解决方案。

子查询能够动态地计算聚合函数。 例如,找到这本书的最低价格,并得到所有以这个价格出售的书。 1)使用子查询:

SELECT titles, price
FROM Books, Orders
WHERE price = 
(SELECT MIN(price)
 FROM Orders) AND (Books.ID=Orders.ID);

2)使用join

SELECT MIN(price)
     FROM Orders;
-----------------
2.99

SELECT titles, price
FROM Books b
INNER JOIN  Orders o
ON b.ID = o.ID
WHERE o.price = 2.99;

摘自MySQL手册(13.2.10.11将子查询重写为连接):

LEFT [OUTER] JOIN可以比等效的子查询更快,因为服务器可以更好地优化它——这不是MySQL服务器独有的事实。

所以子查询可能比LEFT [OUTER] JOIN慢,但在我看来,它们的优势是可读性略高。