如果條件爲NULL,那麼您將只有一個值的記錄集,爲什麼你需要一個索引到該值?在什麼基礎上它會做排序?所以,你需要做的過濾索引,其中,processedAt不爲空並使用代碼條件將有助於
您需要包括ProcessedAt列在創建索引腳本
包列增加一個例子解釋@馬丁史密斯評論:
表腳本:
Create Table TestKeyLookup
(
id int identity(1,1) primary key -- Created PK which will create clustered Index
,id_for_filteredIndex int NOT NULL
,another_id int NOT NULL
)
插入到表中的記錄:
declare @i int = 50
while @i < 1000000
begin
insert into TestKeyLookup (id_for_filteredIndex, another_id) values (@i, @i+5)
set @i = @i + 10
END
與不同的列條件創建於id_for_FilteredIndex列非聚集過濾指數another_id
create nonclustered index NCI_TestKeyLookup on dbo.TestKeyLookup(id_for_filteredIndex)
where another_id > **673105**
如果我查詢表完全相同的條件,那麼優化器不使用KeyLookup
select count(id_for_filteredIndex) from TestKeyLookup with(index(NCI_TestKeyLookup))
where another_id > 673105

如果我通過增加甚至+5或10來改變條件,那麼它確實keyLookup到聚集索引
select count(id_for_filteredIndex) from TestKeyLookup with(index(NCI_TestKeyLookup))
where another_id > 673110

我試圖解釋這只是..如果在條件的變化,然後它使用KeyLookup獲取。從某種意義上說,如果列是可以空的,並且它是空值,那麼它是不同的
你的感覺是正確的。這是沒有道理的,不應該邏輯上要求。但這是一個從未被修復的優化器限制。你可以在這裏投票https://connect.microsoft.com/SQLServer/feedback/details/454744/filtered-index-not-used-and-key-lookup-with-no-output –
@MartinSmith但是這裏的情況是因爲ProcessedAt與索引的CreatedAt列不同,爲了實現該條件'd.ProccessedAt爲null',它必須使用該值。對於該優化器必須執行鍵查找才能獲得適當的值。你提到的錯誤只有當索引列和謂詞列是相同的。我還沒有檢查行爲雖然.. –
不,你已經錯過了這一點。它在邏輯上不*具有*進行鍵查找來獲得該列。它正在檢查的條件已由過濾的索引條件保證。條件對索引中的所有行都成立。它在邏輯上可以簡單地跳過檢查它作爲OP懷疑。查找的唯一原因是因爲優化器當前不包含該邏輯,但它可以並且應該被添加。 –