8.2.1.8 外加入优化

外部联接包括LEFT JOINRIGHT JOIN

MySQL 实现了A LEFT JOIN B join_specification,如下所示:

  • table* B 设置为取决于 table A 以及 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,如果对于生成的NULLWHERE条件始终为 false,则LEFT JOIN更改为内部联接。例如,如果t2.column1NULL,则在以下查询中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 和视图引用”