Outer joins include 外部联接包括LEFT JOIN
and RIGHT JOIN
.LEFT JOIN
和RIGHT JOIN
。
MySQL implements an MySQL实现了一个
as follows:A
LEFT JOIN B
join_specification
,如下所示:A
LEFT JOIN B
join_specification
Table 表B
is set to depend on table A
and all tables on which A
depends.B
设置为依赖于表A
和A
所依赖的所有表。
Table 表A
is set to depend on all tables (except B
) that are used in the LEFT JOIN
condition.A
被设置为依赖于LEFT JOIN
接条件中使用的所有表(B
除外)。
The LEFT JOIN
condition is used to decide how to retrieve rows from table B
. LEFT JOIN
条件用于决定如何从表B
中检索行。(In other words, any condition in the (换句话说,不使用WHERE
clause is not used.)WHERE
子句中的任何条件。)
All standard join optimizations are performed, with the exception that a table is always read after all tables on which it depends. 所有标准联接优化都会执行,唯一的例外是表总是在它所依赖的所有表之后读取。If there is a circular dependency, an error occurs.如果存在循环依赖项,则会发生错误。
All standard 执行所有标准WHERE
optimizations are performed.WHERE
优化。
If there is a row in 如果A
that matches the WHERE
clause, but there is no row in B
that matches the ON
condition, an extra B
row is generated with all columns set to NULL
.A
中有一行与WHERE
子句匹配,但B
中没有与ON
条件匹配的行,则会生成一个额外的B
行,并将所有列设置为NULL
。
If you use 如果使用LEFT JOIN
to find rows that do not exist in some table and you have the following test:
in the col_name
IS NULLWHERE
part, where col_name
is a column that is declared as NOT NULL
, MySQL stops searching for more rows (for a particular key combination) after it has found one row that matches the LEFT JOIN
condition.LEFT-JOIN
查找某些表中不存在的行,并且进行了以下测试:WHERE
部分的
,其中col_name
IS NULLcol_name
是声明为NOT NULL
的列,MySQL在找到一行与LEFT JOIN
条件匹配后,将停止搜索更多行(针对特定的键组合)。
The RIGHT JOIN
implementation is analogous to that of LEFT JOIN
with the table roles reversed. RIGHT JOIN
实现类似于LEFT JOIN
,但是表角色颠倒。Right joins are converted to equivalent left joins, as described in Section 8.2.1.10, “Outer Join Simplification”.如第8.2.1.10节,“外部联接简化”所述,将右侧联接转换为等效的左侧联接。
For a 对于LEFT JOIN
, if the WHERE
condition is always false for the generated NULL
row, the LEFT JOIN
is changed to an inner join. LEFT JOIN
,如果生成的空行的WHERE
条件始终为false
,则LEFT JOIN
将更改为内部连接。For example, the 例如,如果WHERE
clause would be false in the following query if t2.column1
were NULL
:t2.column1
为NULL
,则以下查询中的WHERE
子句将为false
:
SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;
Therefore, it is safe to convert the query to an inner join:因此,将查询转换为内部联接是安全的:
SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;
In MySQL 8.0.14 and later, trivial 在MySQL 8.0.14及更高版本中,在准备过程中删除常量文本表达式产生的WHERE
conditions arising from constant literal expressions are removed during preparation, rather than at a later stage in optimization, by which time joins have already been simplified. WHERE
条件,而不是在优化的后期阶段,此时连接已经简化。Earlier removal of trivial conditions allows the optimizer to convert outer joins to inner joins; this can result in improved plans for queries with outer joins containing trivial conditions in the 早期移除的琐碎条件允许优化器将外部连接转换为内部连接;这可以改进查询的计划,外部联接在WHERE
clause, such as this one:WHERE
子句中包含一些无关紧要的条件,例如:
SELECT * FROM t1 LEFT JOIN t2 ONcondition_1
WHEREcondition_2
OR 0 = 1
The optimizer now sees during preparation that 0 = 1 is always false, making 优化器现在在准备过程中发现OR 0 = 1
redundant, and removes it, leaving this:0=1
始终为false
,使OR 0=1
成为冗余,并将其删除,留下以下内容:
SELECT * FROM t1 LEFT JOIN t2 ONcondition_1
wherecondition_2
Now the optimizer can rewrite the query as an inner join, like this:现在,优化器可以将查询重写为内部联接,如下所示:
SELECT * FROM t1 JOIN t2 WHEREcondition_1
ANDcondition_2
Now the optimizer can use table 现在,优化器可以在表t2
before table t1
if doing so would result in a better query plan. t1
之前使用表t2
,如果这样做会产生更好的查询计划。To provide a hint about the table join order, use optimizer hints; see Section 8.9.3, “Optimizer Hints”. 要提供关于表连接顺序的提示,请使用优化器提示;请参阅第8.9.3节,“优化器提示”。Alternatively, use 或者,使用STRAIGHT_JOIN
; see Section 13.2.10, “SELECT Statement”. STRAIGHT_JOIN
;请参阅第13.2.10节,“SELECT语句”。However, 然而,STRAIGHT_JOIN
may prevent indexes from being used because it disables semijoin transformations; see Section 8.2.2.1, “Optimizing IN and EXISTS Subquery Predicates with Semijoin Transformations”.STRAIGHT_JOIN
可能会阻止索引的使用,因为它禁用了半联变换;请参阅第8.2.2.1节,“使用半联接转换优化IN和EXISTS子查询谓词”。