Linq compiled query uses clusted index instead of filtered index
1
vote
1
answer
821
views
Given the following table
CREATE TABLE Test(
Id INT PRIMARY KEY IDENTITY(1, 1),
Val INT
)
CREATE UNIQUE INDEX UX_Test_Val ON Test(Val) WHERE Val IS NOT NULL
DECLARE @i INT = 0
WHILE (@i x.Val == 123).FirstOrDefault();
this gets compiled to something similar to
DECLARE @V INT
SELECT TOP 1 Id FROM Test WHERE Val = @V OR (Val IS NULL AND @V IS NULL)
Seems legit. But I am very disappointed when seeing the clustered index scan in the query plan.
The plan looks way better when I remove the second clause.
SELECT TOP 1 Id FROM Test WHERE Val = @V
This time the plan is a non clustered Index Seek with 1 row read
So my first guess is that the filtered index is the evil here and I created a second non-clustered not unique index on the same column
CREATE INDEX IX_Test_Val ON Test(Val)
This time both statements uses the newly created index and yields to the same index seek plan.
Here comes three questions:
1. Why does filtered index has such poor performance in this case?
2. How can I make linq to omit the IS NULL part?
3. Is there a way to enforce unique constrain that allows NULL with just one non filtered index?
Asked by Steve
(169 rep)
Mar 6, 2020, 08:40 PM
Last activity: Mar 6, 2020, 09:25 PM
Last activity: Mar 6, 2020, 09:25 PM