我正在测试一个内部关系数据库,我无法弄清楚优化器可以找出这个查询计划的原因。
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 JOIN
和INNER JOIN
混合使用时,优化程序如何判断INNER_JOIN(INNER_JOIN(B,C),A)
与INNER_JOIN(LEFT_JOIN(A,B),C)
共享相同的结果?
是否有理论来证明这一点或者这种情况只是个案发生?
答案 0 :(得分:1)
计划INNER_JOIN(LEFT_JOIN(A,B),C)
和INNER_JOIN(INNER_JOIN(B,C),A)
的等效性有两个步骤:
INNER_JOIN(LEFT_JOIN(A,B),C)
相当于INNER_JOIN(INNER_JOIN(A,B),C)
INNER_JOIN(INNER_JOIN(A,B),C)
相当于INNER_JOIN(INNER_JOIN(B,C),A)
第一个等价是更难以看到的。执行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
的注释