嵌套查询或连接查询

12

我听说连接应该优先于嵌套查询。这是一般情况下正确的吗?还是可能存在某些情况下其中一种方式比另一种更快:

例如,编写查询的哪种方式更有效?

Select emp.salary 
from employee emp    
where emp.id = (select s.id from sap s where s.id = 111)

或者

Select emp.salary     
from employee emp   
INNER JOIN sap s ON emp.id = s.id   
WHERE s.id = 111

如果where条件成为连接条件的一部分呢?INNER JOIN sap s on emp.id = s.id and s.id = 111 - Tim
3个回答

10
我听说连接查询(JOIN)比嵌套查询更好,这种说法普遍正确吗?
这要取决于具体的需求和数据条件。
如果使用 JOIN 连接,它会返回满足匹配条件的行。如果一张父表中存在多个与之相关的子记录,那么在结果集中就可能出现父表信息的重复。因此,如果你想保证在使用 JOIN 的情况下从父表中获取唯一值,你需要使用 DISTINCT 或者 GROUP BY 子句。但是,如果使用子查询,则无需考虑这些问题。
同时,所有的子查询并不相同。像你提到的那样,有一种简单的求值方式。
where emp.id = (select s.id from sap s where s.id = 111)

...以及IN子句:

where emp.id IN (select s.id from sap s where s.id = 111)

当直接评估返回多个值时,它将与子查询返回的任何值匹配,否则将抛出错误。但也有EXISTS子句...

WHERE EXISTS(SELECT NULL 
               FROM SAP s
              WHERE emp.id = s.id
                AND s.id = 111)

EXISTS和IN的不同之处在于:

  • SELECT子句不会被评估 - 你可以将其更改为SELECT 1/0,这应该会触发除以零错误,但实际上不会。
  • 它返回true/false; true是基于满足条件的第一个实例,因此在处理重复项时速度更快。
  • 与IN子句不同,EXISTS支持同时比较两个或多个列比较,但某些数据库支持使用IN进行元组比较。
  • 它更易读

你认为在哪些情况下,IN子句比EXISTS更好用? - Daniel Vassallo
1
@Daniel Vassallo:目前还没有。我想 EXISTS 方法也可以规避 IN 在某些数据库上(成千上万的情况下)需要比较高数量值的问题。 - OMG Ponies

1
如果查询在逻辑上等效,则查询优化器应该能够从每个查询中生成相同(最佳)的执行计划。在这种情况下,查询样式应该支持最易理解的内容(对我来说是子查询)。

0

在编程中,使用索引将两个表连接起来比运行两个单独的查询(甚至是子查询)要快得多,而且更易于编写。


但是为什么呢?执行计划有什么区别? - Kirk Woll
没有区别,因为MySQL会优化它,可能使用JOIN并执行相同的操作,但您将看到它运行一个PRIMARY查询和一个SUBQUERY。不确定这是否会影响速度。另一件事是您在语义上连接了两个表,那么为什么不写成这样呢? - Explosion Pills
@tandu,我认为对于许多查询而言,子查询提供了更清晰的表达。如果你只需要从另一个表中获取一条数据,使用子查询将其全部放在一个地方比将其拆分到主查询的select、from/join和where子句中要明显得多 - Kirk Woll
完全不同意。当你使用JOIN时,你要求两个表的关系乘积,即它们的索引匹配的行。而使用子查询时,你是在说,嗯,给我表1中与这个数据片段(一个ID?可能是一个)匹配的所有行。现在,将它们与所有键匹配的另一个(主)表上的所有值进行比较。 - Explosion Pills
3
如果你认为子查询比连接语句难以阅读,那么你就是一只稀有的鸟。 - Kirk Woll

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接