Это вполне ожидаемо.
Когда вы составляете план с параметрами или переменными, он должен создать план, который будет работать для любого возможного значения, которое они могут иметь.
Вы можете добавить OPTION (RECOMPILE)
в инструкцию, чтобы их значения во время выполнения учитывались (в основном они заменяются литералами со значением времени выполнения), но это будет означать перекомпиляцию при каждом выполнении.
Вероятно, вам лучше всего иметь два отдельных запроса , один для случая, обрабатываемого отфильтрованным индексом, и один для других случаев.
Вы могли надеяться, что SQL Сервер сделает что-то подобное ниже и динамически переключится между сканированием кластерного индекса + сортировкой и сканирование отфильтрованного индекса и отсутствие сортировки (фильтры имеют предикаты запуска, поэтому выполняется не более одной ветви)
Но для получения этого плана необходимо было изменить отфильтрованный индекс для перемещения Name
в ключевые столбцы, как показано ниже ...
CREATE NONCLUSTERED INDEX [NonClusteredIndex-20200508-225254]
ON [dbo].[Students] ([CreatedOn] ASC, [Name] asc)
WHERE ([Active] = (1) AND [Deleted] = (0))
... и переписывание запроса t о
DECLARE @Active BIT = 1
DECLARE @Deleted BIT = 0
SELECT NAME,
CreatedOn
FROM dbo.Students WITH (INDEX =[NonClusteredIndex-20200508-225254])
WHERE Active = 1
AND Deleted = 0
AND 1 = 1 /*Prevent auto parameterisation*/
AND ( @Active = 1 AND @Deleted = 0 )
UNION ALL
SELECT NAME,
CreatedOn
FROM dbo.Students
WHERE Active = @Active
AND Deleted = @Deleted
AND NOT ( @Active = 1
AND @Deleted = 0 )
ORDER BY CreatedOn
OPTION (MERGE UNION)