为什么对索引列的不等式搜索会给出恒定的扫描

SEa*_*986 7 sql-server execution-plan sql-server-2019 query-performance

使用 StackOverflow2010 数据库,我可以在 users 表上创建索引,如下所示:

CREATE INDEX IX_DisplayName ON dbo.Users
(
    DisplayName,
    UpVotes
)
Run Code Online (Sandbox Code Playgroud)

然后对索引的键运行不等式搜索:

SELECT  DisplayName,
        UpVotes
FROM    Users
WHERE   DisplayName <> N'Alex'
Run Code Online (Sandbox Code Playgroud)

我在这里得到计划

我正在尝试弄清楚 SQL Server 如何获取此查询的结果。

该计划从一些持续扫描开始,但输出列表是空白的,因此我不清楚它们的用途。

然后,每个恒定扫描进入一个计算标量,每个计算标量输出

Compute Scalar Node6
Expr1002 = 10
Expr1003 = NULL
Expr1004 = N'Alex'

Compute Scalar Node9 
Expr1005 = 6 
Expr1006 = N'Alex' 
Expr1007 = NULL
Run Code Online (Sandbox Code Playgroud)

然后,连接运算符似乎连接了上面的一些输出:

Expr1010 = Expr1008,Expr1006
Expr1011 = Expr1004,Expr1009
Expr1012 = Expr1002,Expr1005
Run Code Online (Sandbox Code Playgroud)

但它有我在计划中看不到的输入(Expr 1008 和 Expr1009)

我也不知道为什么需要TOP N排序

索引搜索是有意义的 - 它正在寻找 > Expr1011 和 < Expr1012。我认为这基本上是这样的

>= 'a' AND < 'Alex' 
Run Code Online (Sandbox Code Playgroud)

或者

> 'Alex' AND <= 'zzzzzzzzzzzzzz'
Run Code Online (Sandbox Code Playgroud)

或类似的。

有人可以逐步向我解释这个计划是如何运作的,以及我如何理解由串联运算符生成的 Expr1011 和 Expr1012 (用于索引查找)的值

Cha*_*ace 7

这似乎是由Simple ParameterizationDynamic Seek的组合引起的。

在某些情况下,SQL Server 会将未参数化的查询参数化。但这有时会导致隐式转换出现问题。

这里发生的事情是它已经转换N'Alex'@1 nvarchar(4000) = 'Alex'. 然后它将其转换WHERE DisplayName <> @1Dynamic Seekvarchar由于您的原始查询不是 ,因此基数估计可能不准确nvarchar

这可能有一些缺点,特别是在基数估计方面,但它确实有一个好处,即服务器可以从不等式谓词中寻求两种方式。

换句话说,

WHERE DisplayName <> @1
Run Code Online (Sandbox Code Playgroud)

变成两次搜索,逻辑如下:

WHERE DisplayName < @1 OR DisplayName > @1
Run Code Online (Sandbox Code Playgroud)

这里实际上不需要 and ,因为根据定义这两个谓词必须是不相交的,但这是标准的 Dynamic Seek设置SortMerge Interval