【问题标题】:T-SQL different JOIN approaches, same results, which one would you prefer?T-SQL 不同的 JOIN 方法,相同的结果,你更喜欢哪一种?
【发布时间】:2014-02-11 01:32:30
【问题描述】:

这些是如何进行连接的 3 种方法。我想听听关于这 3 个查询的性能的一些消息。 谢谢

SELECT * FROM 
tableA A LEFT JOIN tableB B
    INNER JOIN tableC C
    ON C.ColumnC = B.ColumnB

ON B.ColumnB = A.ColumnB
WHERE ColumnX = 'XY'

对比

SELECT * FROM 
tableA A LEFT JOIN tableB B 
    ON B.ColumnB = A.ColumnB
INNER JOIN tableC C
    ON C.ColumnC = B.ColumnB
WHERE ColumnX = 'XY'

与公用表表达式

WITH T...

【问题讨论】:

  • 使用实际执行计划运行它们并进行调查。很难预测。
  • 我用自己的几张表做了一些测试。前两个结果接缝非常接近。
  • 您是否在第一个代码块中缺少一些括号? tableB 的 JOIN 条件在 tableC 上的 INNER JOIN 之后?
  • @NickyvV - 这是完全有效的 T-SQL。这意味着,首先执行 TableB 和 TableC 之间的 INNER JOIN。然后将生成的表左连接到 TableA。
  • 就个人而言,我将我的 INNER JOIN 保持在顶部。在此示例中,我将有一个带有左连接的 CTE。在此之下,我将在 TableC 上进行内部连接。

标签: tsql left-join inner-join database-performance


【解决方案1】:

没关系。

SQL Server 具有基于成本的优化器(与基于规则的优化器相对)。这意味着引擎能够确定您的前两个选项是相同的。运行您估计的和实际的执行计划,您会发现确实如此。

您选择一个选项而不是另一个选项的唯一原因是为了便于阅读。我选择您的第二个选项,因为当涉及大量连接时,它更容易阅读。反向顺序的 ON 子句变得很难跟踪。

【讨论】:

    【解决方案2】:

    根据我的经验,根据您的桌子,上述任何方法都可能更快。

    在设置联接时,您希望从尽可能严格的开始(显然不会对最终结果产生负面影响)。出于同样的原因,同样的逻辑也适用于 Where 子句。通过从最严格的开始,您限制了正在连接的行数,因此由 Where 子句评估,然后在 select 子句中返回/操作。对于下面关于三个特定场景的答案,我假设一个足够复杂的查询,它不仅仅是寻找组合来自多个表的数据(即,回答特定问题的查询)。

    如果表 A 很大,而表 B 和 C 较小并且与您要隔离的数据更直接相关,那么第一个选项可能最快。

    如果表 B 或 C 很大,而表 A 与您想要的数据更相关,则第二个选项可能最快。

    就选项 3 而言,我喜欢 CTE,但我尝试仅在我需要时使用它们。如果 CTE 连接、操作和返回的数据仅以有限的方式与查询的其余部分相关,则使用 CTE 将加速您的整体查询。在主连接字符串中包含仅与最终结果部分相关的表会不必要地减慢查询速度。如果您可以将这些数据解析为 CTE,它可以自行快速运行,然后在最后重新合并到主查询中。

    【讨论】:

    • 讨厌这样做,但是-1。 SQL Server 有一个基于成本的优化器。它绝对不会根据 T-SQL 中子句的顺序来决定查询计划,尽管不同的结构,例如使用 EXISTS 子句与 JOIN,或外部与内部联接,将改变语义,从而改变执行速度。
    • 所以指定内连接与外连接是否首先发生不会影响性能,但是将内连接更改为外连接或反之亦然?老实问。
    • 通常是这样,但这取决于表之间的关系。由于连接的语义不同(也就是说,由于可能返回不同的行),因此性能和计划通常会有所不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2011-10-20
    • 2011-06-29
    相关资源
    最近更新 更多