连接顺序在SQL中是否重要?

时间:2012-03-08 08:48:31

标签: sql join relational-database

无视性能,我会从下面的查询A和B得到相同的结果吗? C和D怎么样?

-- A
select *
from   a left join b
           on <blahblah>
       left join c
           on <blahblan>


-- B
select *
from   a left join c
           on <blahblah>
       left join b
           on <blahblan>  

-- C
select *
from   a join b
           on <blahblah>
       join c
           on <blahblan>


-- D
select *
from   a join c
           on <blahblah>
       join b
           on <blahblan>  

4 个答案:

答案 0 :(得分:193)

对于INNER加入,不,顺序无关紧要。只要您将选择从SELECT *更改为SELECT a.*, b.*, c.*,查询就会返回相同的结果。


对于(LEFTRIGHTFULLOUTER加入,是的,订单很重要 - 并且( 已更新 < / strong>)事情要复杂得多。

首先,外连接不可交换,因此a LEFT JOIN bb LEFT JOIN a

不同

外部联接也不是关联的,因此在您的示例中涉及(交换性和关联性)属性:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id
  LEFT JOIN c
    ON c.ac_id = a.ac_id

相当于

a LEFT JOIN c 
    ON c.ac_id = a.ac_id
  LEFT JOIN b
    ON b.ab_id = a.ab_id

但:

a LEFT JOIN b 
    ON  b.ab_id = a.ab_id
  LEFT JOIN c
    ON  c.ac_id = a.ac_id
    AND c.bc_id = b.bc_id

不等于

a LEFT JOIN c 
    ON  c.ac_id = a.ac_id
  LEFT JOIN b
    ON  b.ab_id = a.ab_id
    AND b.bc_id = c.bc_id

另一个(希望更简单)的关联性示例。可以将其视为(a LEFT JOIN b) LEFT JOIN c

a LEFT JOIN b 
    ON b.ab_id = a.ab_id          -- AB condition
 LEFT JOIN c
    ON c.bc_id = b.bc_id          -- BC condition

等同于 <{1}}:

a LEFT JOIN (b LEFT JOIN c)

只是因为我们有“好”的a LEFT JOIN b LEFT JOIN c ON c.bc_id = b.bc_id -- BC condition ON b.ab_id = a.ab_id -- AB condition 条件。 ONON b.ab_id = a.ab_id都是相等检查,不涉及c.bc_id = b.bc_id比较。

您甚至可以与其他运营商或更复杂的运营商有条件:NULLON a.x <= b.xON a.x = 7ON a.x LIKE b.x,这两个查询仍然相同。< / p>

但是,如果其中任何一个涉及ON (a.x, a.y) = (b.x, b.y)或与IS NULL之类的空值相关的函数,例如条件为COALESCE(),那么这两个查询将不相同

答案 1 :(得分:4)

对于常规联接,它没有。 TableA join TableB将生成与TableB join TableA相同的执行计划(因此您的C和D示例将相同)

用于左右连接。 TableA left Join TableBTableB left Join TableA不同,但与TableB right Join TableA

相同

答案 2 :(得分:0)

如果在加入B之前尝试在B的字段上加入C,即:

SELECT A.x, A.y, A.z FROM A 
   INNER JOIN C
       on B.x = C.x
   INNER JOIN b
       on A.x = B.x

您的查询将失败,因此在这种情况下,订单很重要。

答案 3 :(得分:0)

Oracle优化器为内部联接选择表的联接顺序。 Optimizer仅在简单的FROM子句中选择表的连接顺序。 您可以在其网站上查看oracle文档。 对于左,右外部联接,投票率最高的答案是正确的。 优化器为每个表选择最佳的连接顺序以及最佳的索引。连接顺序会影响哪个索引是最佳选择。如果它是内部表,则优化器可以选择索引作为表的访问路径;如果它是外部表,则优化器可以选择索引(并且没有其他条件)。

优化器仅在简单的FROM子句中选择表的连接顺序。大多数使用JOIN关键字的联接被展平为简单的联接,因此优化器选择它们的联接顺序。

优化器不为外部联接选择联接顺序;而是为外部联接选择联接顺序。它使用语句中指定的顺序。

选择连接顺序时,优化器将考虑: 每张桌子的大小 每个表上可用的索引 表上的索引在特定的连接顺序中是否有用 每个联接顺序中每个表要扫描的行数和页面数