Это еще одна головоломка оптимизатора запросов.
Может быть, я просто переоцениваю оптимизаторы запросов, или, может быть, я что-то упустил - поэтому я выкладываю это туда.
У меня простой стол
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.
Я интерпретирую вопрос как то, что вы заинтересованы в оптимизаторах в целом, но с особым интересом к SQL Server. Я проверил ваш сценарий с db2 LUW V11.1:
Оптимизатор в DB2 переписывает второй запрос на первый:
План выглядит так:
Я не знаю много о других оптимизаторах, но у меня такое ощущение, что оптимизатор DB2 считается довольно хорошим даже среди конкурентов.
источник
В этом конкретном запросе даже глупо иметь
CASE
заявление. Вы переходите к одному конкретному случаю! Возможно, это просто деталь конкретного примера запроса, который вы дали, но если нет, вы можете написать этот запрос, чтобы получить эквивалентные результаты:Это даст вам точно такой же набор результатов, и, поскольку вы в
CASE
любом случае уже жестко кодируете значения в выражении, вы не теряете здесь никакой возможности сопровождения.источник
CASE
утверждение, потому что ORM делают подобные вещи. Что глупого в том, что вы не узнали этих простых аспектов проблемы ... (как это для того, чтобы косвенно называться безмозглым?)CASE
утверждение может быть полностью исключено без недостатка. Из конечно там могут быть неизвестные факторы, но они не определено.