【问题标题】:Nested Query or Joins嵌套查询或联接
【发布时间】:2011-04-23 06:11:27
【问题描述】:

我听说联接应该优先于嵌套查询。一般情况下是这样吗?或者可能存在一个比另一个更快的情况:

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

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 条件成为连接条件的一部分呢? emp.id = s.id 和 s.id = 111 上的 INNER JOIN sap

标签: sql sql-server tsql join


【解决方案1】:

在一个索引上连接两个表比运行两个单独的查询(甚至是一个子查询)要快得多(并且更容易编写)。

【讨论】:

  • 但是为什么呢?执行计划有什么区别?
  • 没有区别,因为 MySQL 将优化它以可能使用 JOIN 并执行相同的操作,但您会看到它运行 PRIMARY 查询和 SUBQUERY。不确定这是否会影响速度。另一件事是你在语义上连接这两个表,那么为什么不写这个呢?
  • @tandu,我认为对于很多查询,子查询提供了更多的清晰度。如果您只想要另一个表中的一条数据,那么将它全部放在一个位置(使用子查询)比将其拆分为 select、from/join 更清楚 ,并且可能是主查询的 where 子句。
  • 完全不同意。当您加入时,您要求的是两个表的关系乘积,即它们的索引(索引?)匹配的行。使用子查询,你说,嗯,给我表 1 中与这条数据匹配的所有行(一个 ID?可能是一个)。现在,将它们与键匹配的其他(主)表上的所有值进行比较。
  • 哇。如果您认为子查询单方面的可读性不如连接,那您就是一只稀有鸟。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    我听说联接应该优先于嵌套查询。一般情况下是这样吗?

    这取决于需求和数据。

    如果有多个与其相关的子记录,则使用 JOIN 可能会在父表的结果集中复制信息,因为 JOIN 返回匹配的行。这意味着如果您在使用 JOIN 时希望父表中的唯一值,则需要查看使用 DISTINCTGROUP 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)
    

    ...如果s.id 返回多个值,则当直接评估将引发错误时,它将匹配子查询返回的任何值。但也有EXISTS 子句...

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

    EXISTS 的不同之处在于:

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

    【讨论】:

    • 您认为在某些情况下IN 子句比EXISTS 更好吗?
    • @Daniel Vassallo:目前没有。我想知道 EXISTS 方法还可以通过与 IN 在某些数据库(数千个)上比较的大量值来规避问题。
    猜你喜欢
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 2023-02-25
    • 2020-03-19
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多