文档首页
MySQL 8.4 参考手册
相关文档 下载此手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  外连接优化

10.2.1.9 外连接优化

外连接包括 LEFT JOINRIGHT JOIN

MySQL 实现 A LEFT JOIN B join_specification 如下

  • B 设置为依赖于表 A 以及 A 所依赖的所有表。

  • A 设置为依赖于 LEFT JOIN 条件中使用的所有表(除了 B)。

  • LEFT JOIN 条件用于决定如何从表 B 中检索行。(换句话说,WHERE 子句中的任何条件都不会被使用。)

  • 执行所有标准连接优化,但有一点例外,即一个表始终在其依赖的所有表之后读取。如果存在循环依赖,则会发生错误。

  • 执行所有标准 WHERE 优化。

  • 如果表 A 中存在与 WHERE 子句匹配的行,但表 B 中不存在与 ON 条件匹配的行,则会生成一个额外的 B 行,其中所有列都设置为 NULL

  • 如果使用 LEFT JOIN 查找某些表中不存在的行,并且在 WHERE 部分执行以下测试:col_name IS NULL,其中 col_name 是一个声明为 NOT NULL 的列,则在找到与 LEFT JOIN 条件匹配的一行后,MySQL 会停止搜索更多行(对于特定键组合)。

RIGHT JOIN 的实现类似于 LEFT JOIN,只是表角色颠倒。右连接将转换为等效的左连接,如 第 10.2.1.10 节,“外连接简化” 中所述。

对于 LEFT JOIN,如果 WHERE 条件对于生成的 NULL 行始终为假,则 LEFT JOIN 将更改为内部连接。例如,如果 t2.column1NULL,则以下查询中的 WHERE 子句将为假

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;

由常量字面表达式产生的微不足道的 WHERE 条件将在准备阶段被移除,而不是在优化的后期阶段被移除,此时连接已经被简化。尽早移除微不足道的条件可以让优化器将外连接转换为内部连接;这会导致包含 WHERE 子句中微不足道条件的外连接的查询的计划得到改进,例如以下查询

SELECT * FROM t1 LEFT JOIN t2 ON condition_1 WHERE condition_2 OR 0 = 1

优化器现在在准备阶段看到 0 = 1 始终为假,使得 OR 0 = 1 冗余,并将其移除,留下以下代码

SELECT * FROM t1 LEFT JOIN t2 ON condition_1 where condition_2

现在优化器可以将查询重写为内部连接,如下所示

SELECT * FROM t1 JOIN t2 WHERE condition_1 AND condition_2

现在,如果这样做会产生更好的查询计划,优化器可以使用表 t2 而不是表 t1。若要提供关于表连接顺序的提示,请使用优化器提示;请参阅 第 10.9.3 节,“优化器提示”。或者,使用 STRAIGHT_JOIN;请参阅 第 15.2.13 节,“SELECT 语句”。但是,STRAIGHT_JOIN 可能阻止索引被使用,因为它会禁用半连接变换;请参阅 使用半连接变换优化 IN 和 EXISTS 子查询谓词