Dies ist ein weiteres Rätsel des Abfrageoptimierers.
Vielleicht überschätze ich nur die Abfrageoptimierer, oder vielleicht fehlt mir etwas - also stelle ich es da raus.
Ich habe einen einfachen Tisch
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])
mit einem Index und einigen tausend Zeilen, Number
die gleichmäßig in den Werten 0, 1 und 2 verteilt sind.
Nun diese Abfrage:
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;
Sucht ein Index so, IX_Number
wie man es erwarten würde?
Wenn die where-Klausel ist
WHERE P.Name = 'one';
Es wird jedoch ein Scan.
Die case-Klausel ist offensichtlich eine Bijektion, daher sollte theoretisch eine Optimierung möglich sein, um den ersten Abfrageplan von der zweiten Abfrage abzuleiten.
Es ist auch nicht rein akademisch: Die Abfrage ist inspiriert von der Übersetzung von Enum-Werten in ihre jeweiligen Anzeigenamen.
Ich würde gerne von jemandem hören, der weiß, was von Abfrageoptimierern erwartet werden kann (und insbesondere von dem in SQL Server): Erwarte ich einfach zu viel?
Ich frage, wie ich es zuvor getan habe, in denen eine geringfügige Variation einer Abfrage eine Optimierung plötzlich ans Licht bringen würde.
Ich verwende SQL Server 2016 Developer Edition.