使用 StackOverflow2010 数据库,我可以在 users 表上创建索引,如下所示:
CREATE INDEX IX_DisplayName ON dbo.Users
(
DisplayName,
UpVotes
)
然后对索引的键运行不等式搜索:
SELECT DisplayName,
UpVotes
FROM Users
WHERE DisplayName <> N'Alex'
我在这里得到计划
我正在尝试弄清楚 SQL Server 如何获取此查询的结果。
该计划以一些持续扫描开始,但输出列表是空白的,所以我不清楚它们的用途。
然后每个恒定扫描进入一个计算标量,每个计算标量输出
Compute Scalar Node6
Expr1002 = 10
Expr1003 = NULL
Expr1004 = N'Alex'
Compute Scalar Node9
Expr1005 = 6
Expr1006 = N'Alex'
Expr1007 = NULL
然后,连接运算符似乎连接了上面的一些输出:
Expr1010 = Expr1008,Expr1006
Expr1011 = Expr1004,Expr1009
Expr1012 = Expr1002,Expr1005
但它有我在计划中任何地方都看不到的输入(Expr 1008 和 Expr1009)
我也不确定为什么需要 TOP N 排序
索引搜索是有意义的 - 它正在寻找 > Expr1011 和 < Expr1012。我会假设这基本上是这样的
>= 'a' AND < 'Alex'
或者
> 'Alex' AND <= 'zzzzzzzzzzzzzz'
或类似的。
有人可以一步一步地向我解释这个计划是如何工作的,以及我如何理解连接运算符产生的 Expr1011 和 Expr1012 (用于索引搜索)的值
这似乎是由Simple Parameterization和Dynamic Seek的组合引起的。
在某些情况下,SQL Server 将参数化未参数化的查询。但这有时会导致隐式转换出现问题。
这里发生的事情是它已转换
N'Alex'
为@1 nvarchar(4000) = 'Alex'
. 然后它已将其转换WHERE DisplayName <> @1
为Dynamic Seek。基数估计可能不准确,因为您的原始查询varchar
不是nvarchar
.这可能有一些缺点,特别是在基数估计方面,但它确实具有服务器可以从不等式谓词中寻求两种方式的好处。
换句话说,
变成两个搜索,逻辑如下:
这里实际上不需要
Sort
and ,因为这两个谓词根据定义必须是不相交的,但这是标准的 Dynamic Seek 设置。Merge Interval