КОАЛЕСС теперь саркастичен?

9

Один из моих разработчиков утверждает, что COALESCE(column, default value) = default valueтеперь это можно саркастично. Это правильно?

Я COALESCEвыполнил следующий тест, и думаю, что это подразумевает, что это невозможно.

USE tempdb;

SELECT @@VERSION;
-- Microsoft SQL Server 2016 (RTM-CU3-GDR) (KB3194717) - 13.0.2186.6 (X64)   Oct 31 2016 18:27:32   Copyright (c) Microsoft Corporation  Developer Edition (64-bit) on Windows 10 Pro 6.3 <X64> (Build 14393: ) (Hypervisor) 

CREATE TABLE Test 
(
    ID int primary key clustered, 
    Mod6 int null, 
    INDEX IX_Mod6 NONCLUSTERED (Mod6)
);

INSERT INTO Test (ID, Mod6)
SELECT object_id as ID, case when name like '%k%' then null else object_id % 6 end as Mod6
FROM sys.objects;

SELECT Mod6
FROM Test WITH (INDEX = IX_Mod6, FORCESEEK)
where Mod6 is null or Mod6 = 0;
-- Plan shows expected seek

SELECT Mod6
FROM Test WITH (INDEX = IX_Mod6, FORCESEEK)
WHERE COALESCE(Mod6, 0) = 0;
-- Error:
-- Msg 8622, Level 16, State 1, Line 20
-- Query processor could not produce a query plan because of the hints 
-- defined in this query. Resubmit the query without specifying any hints 
-- and without using SET FORCEPLAN.
Митч
источник
5
Ваш разработчик спорил с какими-либо доказательствами?
Аарон Бертран
Я читаю этот пост: josef-richberg.squarespace.com/journal/2010/1/28/… Я не думаю, что конкретный ответ может быть получен, чтобы ответить на этот пост. (Но, может быть, кто-то еще знает лучше.)
RLF
@RLF - в этой статье не сказано ничего, что указывало бы на то, что это можно саркастично. Это не демонстрация того, что это саркастично. twitpic.com/107ms0 . Невозможность сарказма заключается в том, что он предотвращает поиск столбцов, используемых в CASEвыражении, а не то, что результат выражения не может быть использован для поиска чего-то другого.
Мартин Смит
@AaronBertrand, «План выполнения выглядел одинаково, независимо от того, как я его пишу» - он проигнорировал тот факт, что ни один из них не выполнял поиск по COALESCEстолбцу d.
Митч
1
О, я не виню вас за то, что вы задали вопрос, тем более что вы сначала попытались его опровергнуть. Я просто предположил, что, возможно, ваш разработчик должен научиться делать то же самое.
Аарон Бертран

Ответы:

15

Нет COALESCEне саркастично.

Ваш собственный тест хорошо показывает это.

Исключение будет, если вы создали вычисляемый столбец с COALESCEвыражением и проиндексировали его.

CREATE TABLE Test 
(
    ID int primary key clustered, 
    Mod6 int null, 
    Foo AS COALESCE(Mod6, 0),
    INDEX IX_Mod6 NONCLUSTERED (Mod6),
    INDEX IX2_Mod6 NONCLUSTERED (Foo),
);

Вы можете закончить с поиском на этом

SELECT Mod6
FROM Test WITH (INDEX = IX2_Mod6, FORCESEEK)
WHERE COALESCE(Mod6, 0) = 0;

ISNULL незначительно более утомителен тем, что, если он полностью избыточен, его можно оптимизировать, а не предотвратить поиск.

то есть, если столбец Mod6определен как NOT NULLто, следующее может произвести поиск.

SELECT Mod6
FROM Test 
WHERE ISNULL(Mod6, 0) = 0;

Но это, конечно, не дает никакой выгоды, чем просто делать

WHERE Mod6 = 0
Мартин Смит
источник