8.2.1.9 Outer Join Optimization外连接优化

Outer joins include LEFT JOIN and RIGHT JOIN.外部联接包括LEFT JOINRIGHT JOIN

MySQL implements an A LEFT JOIN B join_specification as follows:MySQL实现了一个A LEFT JOIN B join_specification,如下所示:

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.column1NULL,则以下查询中的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 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. 在MySQL 8.0.14及更高版本中,在准备过程中删除常量文本表达式产生的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 ON condition_1 WHERE condition_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 ON condition_1 where condition_2

Now the optimizer can rewrite the query as an inner join, like this:现在,优化器可以将查询重写为内部联接,如下所示:

SELECT * FROM t1 JOIN t2 WHERE condition_1 AND condition_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子查询谓词”