Sql-Server

為什麼對索引列的不等式搜尋會給出恆定掃描

  • September 7, 2022

使用 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 &lt; 'Alex' 

或者

> 'Alex' AND &lt;= 'zzzzzzzzzzzzzz'

或類似的。

有人可以一步一步地向我解釋這個計劃是如何工作的,以及我如何理解連接運算符產生的 Expr1011 和 Expr1012 (用於索引搜尋)的值

這似乎是由Simple ParameterizationDynamic Seek的組合引起的。

在某些情況下,SQL Server 將參數化未參數化的查詢。但這有時會導致隱式轉換出現問題。

這裡發生的事情是它已轉換N'Alex'@1 nvarchar(4000) = 'Alex'. 然後它已將其轉換WHERE DisplayName &lt;&gt; @1Dynamic Seek。基數估計可能不准確,因為您的原始查詢varchar不是nvarchar.

這可能有一些缺點,特別是在基數估計方面,但它確實具有伺服器可以從不等式謂詞中尋求兩種方式的好處。

換句話說,

WHERE DisplayName &lt;&gt; @1

變成兩個搜尋,邏輯如下:

WHERE DisplayName &lt; @1 OR DisplayName &gt; @1

這裡實際上不需要Sortand ,因為這兩個謂詞根據定義必須是不相交的,但這是標準的 Dynamic Seek 設置。Merge Interval

引用自:https://dba.stackexchange.com/questions/316480