Если условие равно NULL, у вас будет только одно значение для набора записей и для чего вам нужен индекс для этого значения? На каком основании он будет сортировать? Так что вам нужно сделать фильтрованный индекс, где processedAt не равно нуля и использовать это условие в коде поможет
Вам нужно включить столбец ProcessedAt в ВКЛЮЧЕННОГО колонка в сценарии создания индекса
Добавление примера для объяснения @Martin Смита комментарий:
Таблица сценария:
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
Создание Non кластерного отфильтрованный индекса на столбце 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
![It does use filtered index](https://i.stack.imgur.com/eraf6.png)
Если я изменяю условие, увеличивая даже +5 или 10, тогда он делает keyLookup для кластеризованного индекса
select count(id_for_filteredIndex) from TestKeyLookup with(index(NCI_TestKeyLookup))
where another_id > 673110
![Different Id where another_id is greater than filtered index condition](https://i.stack.imgur.com/znu1W.png)
Я пытаюсь объяснить это только .. Если есть изменение в состоянии, то он использует KeyLookup для извлечения. В некотором смысле вы правы, если столбец имеет значение NULL, и он имеет нулевые значения, тогда он отличается
Ваши чувства верны. Это не имеет смысла и не требует логического объяснения. Но это ограничение оптимизатора никогда не было исправлено. Вы можете проголосовать за него здесь 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. Единственная причина, по которой это происходит, заключается в том, что оптимизатор в настоящее время не содержит эту логику, но ее можно и нужно добавить. –