据我了解文档,嵌套循环运算符是一个连接运算符,即它需要两个表作为输入。
如果这是正确的,那么为什么嵌套循环运算符与标量输入一起使用?
例如,采用以下查询(来自 Paul White 的网站)及其执行计划。您可以看到嵌套循环运算符的输入是 (1) 标量和 (2) 表(索引查找的结果)。
我知道标量不能与表连接,那么这实际上意味着什么?究竟加入了什么?
USE AdventureWorks2019;
DECLARE @Like nvarchar(50) = N'D%';
SELECT p.[Name]
FROM Production.Product AS p
WHERE p.[Name] LIKE @Like;
顺便说一句,我认为这是一个非常基本的问题,但我找不到一个很好的资源来从方法上讲这些基础知识,所以非常感谢推荐。
这个问题是基于对这些运营商所做的事情的误解:
恒定扫描
此运算符返回一个常量表。这可以是一行或多行,并且可以是从零到多列的任何位置。
在这个特定的例子中,恒定扫描是一行零列。它仅用于为 Compute Scalar 生成驱动行,有点像
(VALUES())
如果可能的话。计算标量
该运算符将一列或多列添加到通过它的行中,其计算可能依赖于也可能不依赖于其他列。它不添加行,它一次在每一行上工作。
在这种情况下,编译器使用它来计算谓词的起点和终点
LIKE
,以及有关谓词的内部信息。嵌套循环
然后将单行馈入连接,并将计算作为相关参数(外部引用)传递。
实际上,查询变成了这样:
标量输入也可以表示为单行单列表。
这正是Constant Scan和 Compute Scalar 运算符所做的 - 将其转换为表格,以便随后可以加入:
并且由于在要连接的两个表之一非常小时(约 10 行或更少)时使用嵌套循环,因此在使用标量输入时您很可能会获得嵌套循环连接。更重要的是,只有嵌套循环 join 支持相关参数(外部引用),也称为apply。
一些更深入的解释: