Navicat 博客

嵌套连接的说明 2022 年 5 月 26 日,由 Robert Gravelle 撰写

就在你以为你知道每种类型的连接时,又有一种出现!也许你听说过嵌套联接,甚至是嵌套循环查询计划,并且想知道它们是什么。好吧,今天的文章将为你解开谜团!

术语案例

在关系数据库中,同一事物可以有许多不同的名称。联接也不例外。事实上,当谈到嵌套联接时,数据库从业者会根据他们对嵌套联接的看法而有所不同。有人说没有这回事;也有人更务实,承认它们只是多表联接的替代术语。

该术语很可能是在提到嵌套循环查询计划时出现的。查询引擎经常使用这些来回答联接。在其最原始的形式中,嵌套循环是这样的:

for all the rows in outer table 
  for all the rows in the inner table 
    if outer_row and inner row satisfy the join condition 
      emit the rows 
  next inner 
next outer

这是最简单但也是最慢的嵌套循环类型。同时,多表嵌套循环联接的性能更差,因为它们随着所有表中的行数乘积的增长而急剧扩展。

嵌套循环的一种更有效的形式是 nested-loop-over-index:

for all the rows that pass the filter from the outer table 
  use join qualifier from outer table row on index on inner table 
    if row found using index lookup 
      emit the rows 
next outer 

嵌套联接语法

现在我们已经确定术语“嵌套联接”只是指两个以上表之间的联接,让我们快速看一下它们的语法。

通常,当我们需要联接多个表和/或视图时,我们会使用以下泛型格式逐一列出:

FROM  Table1 
[ join type ] JOIN Table2 
                ON condition2 
[ join type ] JOIN Table3 
                ON condition3 

但这不是唯一的方法。SQL 的官方 ANSI 语法标准提出了另一种编写上述联接的有效方法:

FROM  Table1 
[ join type ] JOIN Table2 
[ join type ] JOIN Table3 
                ON condition3 
                ON condition2 

为了使上述联接样式更易于人们阅读,我们可以添加括号和缩进以使其更清晰:

FROM  Table1 
[ join type ] JOIN ( Table2 
                    [ join type ] JOIN Table3 
                                    ON condition3 ) 
                ON condition2 

现在更容易看到 Table2 和 Table3 之间的联接是首先指定的,并且必须先完成,然后再联接到 Table1。此查询样式还将 Table2 和 Table3 之间的联接定位为似乎是嵌套的。而实际上,我们可以认为 Table2 和 Table3 之间的联接是嵌套的。

以下是 Navicat Premium 中以两种样式编写的相同查询:

syntax_comparison (98K)

总结

今天的文章阐述了“嵌套联接”和“嵌套循环查询计划”这两个术语。因此,下次你听到它们时,要意识到它们只是指联接多个表或视图,而不管使用了哪种语法。

Navicat 文章
频道条目
分享
文章归档