4.7 外部连接简化
FROM
在许多情况下,查询子句中的 表表达式都得到了简化。
在解析器阶段,具有右外部联接操作的查询将转换为仅包含左联接操作的等效查询。在一般情况下,执行转换时要进行以下右连接:
成为以下等效的左联接:
形式的所有内部联接表达式T1 INNER JOIN T2 ON P(T1,T2)
都由list替换 T1,T2
,P(T1,T2)
作为WHERE
条件(或嵌入联接的联接条件,如果有)的联接而联接。
当优化程序评估外部联接操作的计划时,它仅考虑计划,其中对于每个此类操作,在访问内部表之前访问外部表。由于只有这样的计划才能使用嵌套循环算法执行外部联接,因此优化器的选择受到限制。
考虑这种形式的查询,其中R(T2)
大大缩小了table中匹配行的数量 T2
:
如果查询以书面形式执行,则优化器别无选择,只能在限制程度T1
更高的表之前访问限制程度较小的 表 T2
,这可能会产生效率很低的执行计划。
相反,如果WHERE
条件为空,则MySQL将查询转换为无外部联接操作的查询。(也就是说,它将外部联接转换为内部联接。)如果条件求值FALSE
或UNKNOWN
为该NULL
操作生成的任何 互补行,则条件被认为是null拒绝 的。
因此,对于此外部联接:
诸如此类的条件将被拒绝为null,因为它们对于任何NULL
补行( T2
列设置为NULL
)都无法成立:
诸如此类的条件不能为空,因为它们对于NULL
-补行可能是正确的:
检查外部联接操作的条件是否为空的通用规则很简单:
它的形式为
A IS NOT NULL
,其中哪里A
是任何内部表的属性这是一个谓词,包含对内部表的引用,该内部表的求值是
UNKNOWN
何时其参数之一为NULL
它是一个包含空值拒绝条件作为连接词的连接词
它是零值拒绝条件的析取
对于查询中的一个外部联接操作,条件可以为null拒绝,而对于另一项则不能为null。在此查询中,WHERE
第二个外部联接操作的条件为空,但第一个条件的条件为空:
如果WHERE
查询中的外部联接操作拒绝该条件为空,则将外部联接操作替换为内部联接操作。
例如,在前面的查询中,第二个外部联接被拒绝为空,并且可以由内部联接代替:
对于原始查询,优化器仅评估与单个表访问顺序兼容的计划 T1,T2,T3
。对于重写的查询,它还会考虑访问顺序 T3,T1,T2
。
一种外部联接操作的转换可能触发另一种外部联接操作的转换。因此,查询:
首先转换为查询:
相当于查询:
其余的外部联接操作也可以由内部联接代替,因为该条件T3.B=T2.B
被拒绝为空。这导致根本没有外部联接的查询:
有时,优化器成功替换了嵌入的外部联接操作,但是无法转换嵌入的外部联接。以下查询:
转换为:
只能将其重写为仍包含嵌入外部联接操作的表单:
在查询中转换嵌入式外部联接操作的任何尝试都必须考虑将外部联接嵌入条件的联接 WHERE
条件。在此查询中,WHERE
嵌入的外部联接的 条件不为空,但嵌入外部联接的联接条件T2.A=T1.A AND T3.C=T1.C
为空:
因此,查询可以转换为:
Last updated