【问题标题】:SQL Server : does order of full outer join matter?SQL Server:完全外连接的顺序重要吗?
【发布时间】:2012-05-21 11:43:13
【问题描述】:

我的查询中有 4 个全外连接,而且速度非常慢,那么FULL OUTER JOIN 的顺序是否会影响性能/结果?

全外连接 = ⋈

那么,

我有一种情况:A ⋈ B ⋈ C ⋈ D

所有连接都发生在所有 A、B、C、D 中包含的所有 k 共有的键上

然后:

  • 更改 ⋈ 连接的顺序会影响性能吗?
  • 改变⋈的顺序会改变结果吗?

我觉得应该不会影响结果,但是会不会影响性能我不确定!

更新:

假设结果集独立于顺序,SQL Server 是否会自动重新排列连接以获得更好的性能?

【问题讨论】:

  • 结果应该是一样的。检查性能相当容易。比较将表格从几个匹配项到多个匹配项排序所需的时间与相反的顺序。
  • 为什么不试试呢?查看不同组合的执行计划和 SQL Profiler 跟踪?
  • 当你说不同的顺序时,你的意思是:(a FULL JOIN b) FULL JOIN c vs a FULL JOIN (b FULL JOIN c) 例如?
  • 是和不是。如果你把最严格的放在第一位,那么查询的其余部分将有更少的东西要加入。但是,如果您至少不能普遍保证这一点,那么以这种方式进行调整将没有多大用处。如果您发布查询计划,我们可能会为您提供更多帮助(只需将 Explain 放在查询之前并运行它,然后将 teh vresuklt 添加到您的问题中)。看看为什么需要这么多完整的外部连接可能会更好。
  • 我在第一个表中有 10 万行。检查它们需要几个小时。我想了解会自动重新安排以获得更好的性能?

标签: sql sql-server join


【解决方案1】:

不,重新排列 JOIN 顺序不应影响性能。 MSSQL(与其他 DBMS 一样)有一个 query optimizer,其工作是为任何给定查询找到最有效的查询计划。一般来说,这些都做得很好 - 所以你不太可能轻易击败优化器。

也就是说,他们确实偶尔会出错。这就是reading an execution plan 发挥作用的地方。您可以添加JOIN hints 来告诉MSSQL 如何加入您的表(此时,排序确实 很重要)。您通常会从最小到最大的表进行排序(不过,对于 FULL JOIN,它可能不太重要)并遵循 rules of thumb 的连接类型。

由于您正在执行FULL JOINS,因此您基本上是从磁盘读取全部 4 个表。这可能非常昂贵。您可能需要重新检查问题,看看是否可以通过其他方式完成。

【讨论】:

  • +1 :致 OP - 重要的是要注意 SQL 不是本机和天真的执行的。它实际上只是一个算法表达式,告诉优化器您的问题的功能描述。优化器然后有效地编译它并执行一个可以被认为几乎完全独立于 SQL 的计划。
【解决方案2】:
  • 改变⋈的顺序会改变结果吗?

不,FULL JOIN 的顺序无关紧要,结果都是一样的。但是请注意,您不能使用这样的东西(以下可能会根据连接顺序给出不同的结果):

SELECT 
    COALESCE(a.id, b.id, c.id, d.id) AS id,  --- Key columns used in FULL JOIN
    a.*, b.*, c.*, d.*                       --- other columns                 
FROM a 
  FULL JOIN b
      ON b.id = a.id
  FULL JOIN c
      ON c.id = a.id
  FULL JOIN d
      ON d.id = a.id ;

你必须使用这样的东西(无论连接顺序如何,结果都没有区别):

SELECT 
    COALESCE(a.id, b.id, c.id, d.id) AS id,   
    a.*, b.*, c.*, d.*                                   
FROM a 
  FULL JOIN b
      ON b.id = a.id
  FULL JOIN c
      ON c.id = COALESCE(a.id, b.id) 
  FULL JOIN d
      ON d.id = COALESCE(a.id, b.id, c.id) ;

  • 更改 ⋈ 连接的顺序会影响性能吗?

考虑到第二次和第三次连接必须在列的COALESCE() 上完成,而不是列本身,我认为只有用足够大的表进行测试才能显示索引是否可以有效使用。

【讨论】:

  • 我没有任何合并情况。另外,请参阅问题中的更新!
  • @Yugal:你这是什么意思?您能否发布 2 个版本的查询,以便我们理解您的意思?如果您不使用COALESCE(),您将如何加入?
  • @Yugal:那么(正如我的回答的第一部分所说)您可能会根据连接顺序得到不同的结果。
  • 如果您不使用合并,那么您将根据顺序混合完全外连接和内连接。你需要合并来做你想做的事。
【解决方案3】:

更改完全外部联接的顺序不应影响性能或结果。唯一会根据完全外连接的顺序受到影响的是使用 SELECT * 时生成的列的默认顺序。您可能仅仅因为尝试对大型表进行多个联接而遇到性能问题。如果没有 where 子句来限制表,您可能会经历数十万个结果。

【讨论】:

    猜你喜欢
    • 2012-03-25
    • 2010-09-07
    • 1970-01-01
    • 2012-01-06
    • 2021-12-10
    • 2018-07-12
    相关资源
    最近更新 更多