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 (用于索引查找)的值
这似乎是由Simple Parameterization和Dynamic Seek的组合引起的。
在某些情况下,SQL Server 会将未参数化的查询参数化。但这有时会导致隐式转换出现问题。
这里发生的事情是它已经转换N'Alex'
成@1 nvarchar(4000) = 'Alex'
. 然后它将其转换WHERE DisplayName <> @1
为Dynamic Seek。varchar
由于您的原始查询不是 ,因此基数估计可能不准确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设置Sort
。Merge Interval