• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 外部联接优化

    外部联接包括LEFT JOINRIGHT JOIN

    MySQL实现如下:A LEFT JOIN Bjoin_specification

    • B被设置为依赖于表A以及所依赖的所有表A
    • 表格A被设置为取决于条件B中使用的所有表格(除外)LEFT JOIN
    • LEFT JOIN条件用于确定如何从table中检索行B。(换句话说,WHERE不使用该子句中的任何条件。)
    • 执行所有标准的连接优化,除了始终在表所依赖的所有表之后读取该表。如果存在循环依赖关系,则会发生错误。
    • WHERE执行所有标准优化。
    • 如果其中有一行A与该WHERE子句匹配,但没有一行B与该ON条件匹配,则将B生成一个额外的行,且所有列均设置为NULL
    • 如果您LEFT JOIN用来查找某张表中不存在的行,并且进行了以下测试:col_name IS NULL在该WHERE部分中,哪里col_name是声明为的列NOT NULL,MySQL找到后将停止搜索更多行(针对特定的键组合)符合LEFT JOIN条件的一行。

    RIGHT JOIN实现类似于LEFT JOIN表角色相反的实现。如“简化外部连接”所述,将右连接转换为等效的左连接。

    对于LEFT JOIN,如果WHERE条件对于生成的NULL行始终为false ,则将LEFT JOIN其更改为内部联接。例如,WHERE如果条款是在下面的查询错误的t2.column1NULL

    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;
    

    在MySQL 8.0.14及更高版本中,WHERE常量常量表达式产生的琐碎条件在准备过程中被删除,而不是在优化的后期阶段被删除,到那时,联接已被简化。尽早删除琐碎的条件可以使优化程序将外部联接转换为内部联接。这可能会导致改进的查询计划,其中包含在WHERE子句中包含琐碎条件的外部联接,例如:

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

    现在,优化器在准备过程中会看到0 = 1始终为false,从而使其具有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。要提供有关表连接顺序的提示,请使用优化程序提示;请参见“优化器提示”。或者,使用STRAIGHT_JOIN;请参见“ SELECT语句”。但是,STRAIGHT_JOIN由于禁用了半联接转换,可能会阻止使用索引。请参见“使用 EXISTS 策略优化子查询”。