多个Join中的SQL查询过程是怎样的?

0 join

我有一个这样的查询:

SELECT *
FROM table_1
     LEFT JOIN table_2 
       ON table_1.ID = table_2.ID
     INNER JOIN table_3
       ON table_1.ID = table_3.ID 
Run Code Online (Sandbox Code Playgroud)

SQL如何处理这个连接?SQL 是否先连接表 1 和表 2,然后将这个新的超级表与表 3 连接?或者它会向另一个方向移动?

ype*_*eᵀᴹ 7

执行的逻辑顺序是您所描述的:

  • 它从FROM分析它的子句开始:

      FROM table_1
           LEFT JOIN table_2 
             ON table_1.ID = table_2.ID
           INNER JOIN table_3
             ON table_1.ID = table_3.ID 
    
    Run Code Online (Sandbox Code Playgroud)
  • 根据优先规则,它变成:

      FROM   (   table_1
               LEFT JOIN 
                 table_2 
               ON 
                 table_1.ID = table_2.ID
             )
           INNER JOIN 
             ( table_3 )
           ON
              table_1.ID = table_3.ID 
    
    Run Code Online (Sandbox Code Playgroud)
  • 所以,是的,它首先(逻辑上)生成table_1 LEFT JOIN table_2 ON table_1.ID = table_2.ID一个“超级”表。

  • 然后它在“超级”表和 table_3 之间进行第二次连接。

  • 然后转到SELECT子句,该子句本质上是按以下顺序排列的 3 个表的所有列:

      SELECT table_1.*, table_2.*, table_3.*
    
    Run Code Online (Sandbox Code Playgroud)
  • 然后它产生结果集。

但实际的执行顺序可能完全不同。RDBMS(SQL Server 或 MySQL 或 Postgres 或 Oracle 或 DB2 或...)它允许选择任何看起来合适的顺序,只要它产生与执行的逻辑顺序相同的结果。

  • 所以如果允许的话它可以重新排列连接的顺序(这取决于复杂的规则,连接是LEFT/RIGHT/INNER/FULL,连接条件是任意的还是与FOREIGN KEY约束条件相同,连接列是否有UNIQUE /PRIMARY 表上的约束等)
  • 不仅可以使用联接顺序,还可以使用不同的联接方法(散列、合并、嵌套循环方法等)或使用并行化。
  • 它还可以根据查询中连接的表上的现有索引来选择各种执行路径。
  • 它如何决定选择哪个执行路径可能取决于更多细节,例如表和索引的统计信息、表的大小、列的宽度以及更多优化器/系统设置。
  • 它还取决于 RDBMS 和版本。不同的RDBMS实现了不同的方法(例如MySQL直到最近才实现哈希连接,我认为Postgres仅在2-3年前实现了并行查询,但具有广泛的不同类型的索引,SQL Server很早以前就具有并行查询,但有些功能是仅适用于企业版等),因此所选择的执行路径可能会因 DBMS 的不同而有所不同,除非对于非常简单的查询。