8.2.1.8 外加入优化
外部联接包括LEFT JOIN
和RIGHT JOIN
。
MySQL 实现了A LEFT JOIN B join_specification
,如下所示:
-
table*
B
设置为取决于 tableA
以及A
*所依赖的所有 table。 -
table*
A
设置为依赖于LEFT JOIN
条件中使用的所有 table(B
*除外)。 -
LEFT JOIN
条件用于决定如何从 table*B
*中检索行。 (换句话说,不使用WHERE
子句中的任何条件.) -
执行所有标准的连接优化,不同之处在于始终在 table 所依赖的所有 table 之后读取该 table。如果存在循环依赖关系,则会发生错误。
-
执行所有标准的
WHERE
优化。 -
如果*
A
中存在与WHERE
子句匹配的行,但B
*中没有与ON
条件匹配的行,则会生成多余的B
*行,并将所有列都设置为NULL
。 -
如果您使用
LEFT JOIN
查找某个 table 中不存在的行,并进行以下测试:WHERE
部分中的col_name IS NULL
,其中*col_name
*是声明为NOT NULL
的列,则 MySQL 停止搜索更多行(对于特定行组合键)找到符合LEFT JOIN
条件的一行。
RIGHT JOIN
的实现类似于LEFT JOIN
的实现,但 table 角色相反。右连接将转换为等效的左连接,如第 8.2.1.9 节“简化外部联接”中所述。
对于LEFT JOIN
,如果对于生成的NULL
行WHERE
条件始终为 false,则LEFT JOIN
更改为内部联接。例如,如果t2.column1
是NULL
,则在以下查询中WHERE
子句为 false:
SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;
因此,将查询转换为内部联接是安全的:
SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;
现在,优化程序可以在 tablet1
之前使用 tablet2
,如果这样做会导致更好的查询计划。要提供有关 table 连接 Sequences 的提示,请使用STRAIGHT_JOIN
;参见第 13.2.9 节“ SELECT 语句”。但是,STRAIGHT_JOIN
可能会禁止使用索引,因为它禁用了半联接转换。参见第 8.2.2.1 节“使用半联接转换优化子查询,派生 table 和视图引用”。