Это еще одна головоломка оптимизатора запросов.
Может быть, я просто переоцениваю оптимизаторы запросов, или, может быть, я что-то упустил - поэтому я выкладываю это туда.
У меня простой стол
CREATE TABLE [dbo].[MyEntities](
[Id] [uniqueidentifier] NOT NULL,
[Number] [int] NOT NULL,
CONSTRAINT [PK_dbo.MyEntities] PRIMARY KEY CLUSTERED ([Id])
)
CREATE NONCLUSTERED INDEX [IX_Number] ON [dbo].[MyEntities] ([Number])
с индексом и несколькими тысячами строк, Number
равномерно распределенными в значениях 0, 1 и 2.
Теперь этот запрос:
SELECT * FROM
(SELECT
[Extent1].[Number] AS [Number],
CASE
WHEN (0 = [Extent1].[Number]) THEN 'one'
WHEN (1 = [Extent1].[Number]) THEN 'two'
WHEN (2 = [Extent1].[Number]) THEN 'three'
ELSE '?'
END AS [Name]
FROM [dbo].[MyEntities] AS [Extent1]
) P
WHERE P.Number = 0;
Индекс ищет, IX_Number
как и следовало ожидать.
Если пункт где
WHERE P.Name = 'one';
однако, это становится сканированием.
Кейс-кейс, очевидно, является биекцией, поэтому в теории должна быть возможность оптимизации, чтобы вычесть первый план запроса из второго запроса.
Это также не чисто академический: запрос основан на переводе значений enum в их дружественные имена.
Я хотел бы услышать от кого-то, кто знает, чего можно ожидать от оптимизаторов запросов (и в частности от Sql Server): я просто слишком многого ожидаю?
Я спрашиваю, как у меня были случаи, когда некоторые небольшие изменения в запросе внезапно выявляли оптимизацию.
Я использую Sql Server 2016 Developer Edition.