我是一个老派的MySQL用户,总是更喜欢JOIN而不是子查询。但是现在每个人都用子查询,我讨厌它;我不知道为什么。
我缺乏理论知识来判断是否有任何不同。子查询是否与JOIN一样好,因此没有什么可担心的?
我是一个老派的MySQL用户,总是更喜欢JOIN而不是子查询。但是现在每个人都用子查询,我讨厌它;我不知道为什么。
我缺乏理论知识来判断是否有任何不同。子查询是否与JOIN一样好,因此没有什么可担心的?
当前回答
只有当第二个连接表的数据明显多于主表时,才会出现这种差异。我有过这样的经历……
我们有一个用户表,有10万个条目,他们的会员数据(友谊)大约有30万个条目。这是一个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;
现在,许多dbs都可以优化子查询和连接。因此,您只需使用explain检查您的查询,看看哪个更快。如果在性能上没有太大的差异,我更喜欢使用子查询,因为它们简单,更容易理解。
根据我的观察,就像两种情况,如果一个表的记录少于10万条,那么连接将工作得很快。
但是如果一个表有超过100,000条记录,那么子查询是最好的结果。
我有一个表,其中有500,000条记录,我在查询下面创建了它,它的结果时间是
SELECT *
FROM crv.workorder_details wd
inner join crv.workorder wr on wr.workorder_id = wd.workorder_id;
结果:13.3秒
select *
from crv.workorder_details
where workorder_id in (select workorder_id from crv.workorder)
结果:1.65秒
我不是关系数据库专家,所以对此持保留态度。
子查询与连接的一般思想是较大查询的求值路径。
为了执行较大的查询,必须首先执行每个子查询,然后将结果集存储为与较大查询交互的临时表。
这个临时表没有索引,因此,任何比较都需要扫描整个结果集。
相反,当您使用连接时,所有索引都在使用中,因此,比较需要遍历索引树(或哈希表),这在速度方面成本要低得多。
现在,我不知道最流行的关系引擎的新版本是否在反向执行求值,只是将必要的元素加载到临时表中,作为优化方法。
子查询是解决“从A获取事实,以B的事实为条件”这种形式的问题的逻辑正确方法。在这种情况下,在子查询中插入B比进行连接更具逻辑意义。从实际意义上讲,它也更安全,因为您不必担心由于与B的多个匹配而从a获得重复的事实。
然而,实际上,答案通常归结于性能。当给出连接和子查询时,一些优化器会很糟糕,而另一些则相反,这是特定于优化器、特定于dbms版本和特定于查询的。
从历史上看,显式连接通常会胜出,因此已经建立的智慧是连接更好,但优化器一直在变得更好,因此我更喜欢先以逻辑一致的方式编写查询,然后在性能限制的情况下重新构造查询。