SQL查询中混合LEFT JOIN和INNER JOIN的执行计划

时间:2017-12-29 19:43:35

标签: sql join relational-database

我正在测试一个内部关系数据库,我无法弄清楚优化器可以找出这个查询计划的原因。

SELECT * from A LEFT JOIN B on A.x = B.x INNER JOIN C on B.y = C.y

此数据库报告的执行计划可以编写如下psuedo-code:

For each tupleB in B
   For each tupleC in C
     INNER JOIN tupleB and tupleC
     For each tupleA in A
         INNER JOIN tupleA

此计划的结果是正确的。

如果所有JOIN都是INNER联接,那么这个计划对我来说是合情合理的,因为INNER JOIN既可交换也有关联。

但是,当LEFT JOININNER JOIN混合使用时,优化程序如何判断INNER_JOIN(INNER_JOIN(B,C),A)INNER_JOIN(LEFT_JOIN(A,B),C)共享相同的结果?

是否有理论来证明这一点或者这种情况只是个案发生?

1 个答案:

答案 0 :(得分:1)

计划INNER_JOIN(LEFT_JOIN(A,B),C)INNER_JOIN(INNER_JOIN(B,C),A)的等效性有两个步骤:

  1. INNER_JOIN(LEFT_JOIN(A,B),C)相当于INNER_JOIN(INNER_JOIN(A,B),C)
  2. INNER_JOIN(INNER_JOIN(A,B),C)相当于INNER_JOIN(INNER_JOIN(B,C),A)
  3. 第一个等价是更难以看到的。执行LEFT_JOIN(A,B)后,A中的行可能没有B中的对应行。这些行是唯一不在INNER_JOIN(A,B)中的行。这些行在B属性中将具有NULL值。随后,使用C使用B.y执行内部联接,并且这些额外的行必须在最终结果中消失,因为B.y为NULL并且连接条件B.y = C.y始终为评估为uknown。因此,在最终结果中,即使您处理INNER_JOIN(A,B),您也只有LEFT_JOIN(A,B)的乘积。

    第二个等价是来自join associativity

    的注释