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

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


当前回答

根据我的观察,就像两种情况,如果一个表的记录少于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秒

其他回答

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

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

使用EXPLAIN查看数据库如何对数据执行查询。这个答案中有一个很大的“视情况而定”……

PostgreSQL可以将子查询重写为连接,或将连接重写为子查询,如果它认为其中一个比另一个快。这完全取决于数据、索引、相关性、数据量、查询等。

如果你想用join加速你的查询:

对于“inner join/join”, 不要使用where条件,而是使用“ON”条件。 例如:

     select id,name from table1 a  
   join table2 b on a.name=b.name
   where id='123'

 Try,

    select id,name from table1 a  
   join table2 b on a.name=b.name and a.id='123'

对于“左/右连接”, 不要在“ON”条件下使用,因为如果你使用左/右连接,它将获得任何一个表的所有行。所以,在"开"里也没用。所以,尝试使用“Where”条件

子查询是解决“从A获取事实,以B的事实为条件”这种形式的问题的逻辑正确方法。在这种情况下,在子查询中插入B比进行连接更具逻辑意义。从实际意义上讲,它也更安全,因为您不必担心由于与B的多个匹配而从a获得重复的事实。

然而,实际上,答案通常归结于性能。当给出连接和子查询时,一些优化器会很糟糕,而另一些则相反,这是特定于优化器、特定于dbms版本和特定于查询的。

从历史上看,显式连接通常会胜出,因此已经建立的智慧是连接更好,但优化器一直在变得更好,因此我更喜欢先以逻辑一致的方式编写查询,然后在性能限制的情况下重新构造查询。

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

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

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