To kolejna zagadka optymalizatora zapytań.
Może po prostu przeszacowuję optymalizatory zapytań, a może coś mi brakuje - więc zamieszczam to.
Mam prosty stół
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])
z indeksem i kilkoma tysiącami wierszy, Number
równomiernie rozmieszczonymi w wartościach 0, 1 i 2.
Teraz to zapytanie:
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;
indeks szuka IX_Number
zgodnie z oczekiwaniami.
Jeśli klauzula gdzie jest
WHERE P.Name = 'one';
staje się jednak skanem.
Klauzula przypadku jest oczywiście bijectionem, więc teoretycznie optymalizacja powinna umożliwić odjęcie pierwszego planu zapytania od drugiego zapytania.
Nie jest to również czysto akademickie: zapytanie jest inspirowane tłumaczeniem wartości wyliczeniowych na ich przyjazne nazwy.
Chciałbym usłyszeć od kogoś, kto wie, czego można się spodziewać po optymalizatorach zapytań (a konkretnie w Sql Server): czy po prostu oczekuję zbyt wiele?
Pytam, tak jak kiedyś miałem przypadki, w których niewielka zmiana zapytania sprawiłaby, że optymalizacja nagle wyszła na jaw.
Używam Sql Server 2016 Developer Edition.