示例模式:爲什麼優化器不使用我獨特的過濾索引?
create table dbo.Person (
ID int identity(1,1) not null
constraint PK_Person primary key,
UserName nvarchar(50) null,
EncryptedPassword nvarchar(100) null
)
create index IX_Person_Login
on dbo.Person (UserName, EncryptedPassword)
include (/* other columns */)
create unique index IX_Person_UserName
on dbo.Person (UserName)
where (UserName is not null)
所以,現在,如果我的用戶名做ID的查找,我希望的是更小,更選擇性指數將優化選擇。 IX_Person_UserName也應該被覆蓋,因爲ID是聚類關鍵(並且生成的計劃確實承擔了這一點,但這不是問題的關鍵)。
select ID
from dbo.Person
where UserName = @UserName
and UserName is not null
然而相反,優化選擇執行索引查找上IX_Person_Login,這不是唯一的,在關鍵的列多,並且其葉子節點大得多。如果我強制使用IX_Person_UserName,估計的成本是相同的。在這兩種情況下,估計的行數都超過了100,但實際的行數是1.我嘗試更新統計數據,但是在選擇的計劃或估計的行數方面沒有任何區別。是否因爲SQL Server的計劃考慮到@ UserName可能爲空的可能性?即使我在查詢中放置了一個字符串非空字符串值,它仍然不會使用唯一的已過濾索引。誰能解釋這種行爲?
嘗試包括在索引中的ID – mxix 2014-09-26 16:39:02
@mxix沒有必要,因爲它是聚簇索引 – Lamak 2014-09-26 16:44:47
@Lamak,他想對給定的ID。由於IX_Person_Username不包含該ID,因此不會使用該ID。如果IX_Person_Username包含ID,優化器可能會爲給定的查詢選擇它。 –
mxix
2014-09-26 16:51:48