COALESCE è ora disponibile?


9

Uno dei miei sviluppatori sta sostenendo che COALESCE(column, default value) = default valueora è sargable. È giusto?

Ho eseguito il seguente test e penso che implichi che COALESCEnon è possibile effettuare ricerche.

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
Il tuo sviluppatore ha discusso con qualsiasi prova?
Aaron Bertrand

Ho letto questo post: josef-richberg.squarespace.com/journal/2010/1/28/… Non credo che si possa derivare una risposta concreta per rispondere a questo post. (Ma forse qualcun altro lo sa meglio.)
RLF

@RLF - quell'articolo non dice nulla che indichi che è ampio. Questa non è una dimostrazione della sua ampiezza. twitpic.com/107ms0 . La non sargability è che impedisce una ricerca sulle colonne utilizzate CASEnell'espressione, non che il risultato dell'espressione non possa quindi essere utilizzato per cercare qualcos'altro.
Martin Smith,

@AaronBertrand, "Il piano di esecuzione sembrava lo stesso, non importa come lo scrivo" - Ha ignorato il fatto che nessuno dei due stava eseguendo una ricerca in base alla COALESCEcolonna d.
Mitch,

1
Oh, non ti lamento per aver posto la domanda, specialmente da quando hai tentato di confutarla per prima. Stavo solo suggerendo che forse il tuo sviluppatore dovrebbe imparare a fare lo stesso.
Aaron Bertrand

Risposte:


15

No COALESCEnon è sargable.

Il tuo test lo dimostra bene.

Un'eccezione sarebbe se hai creato una colonna calcolata con l' COALESCEespressione e indicizzata quella.

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),
);

Potresti finire con una ricerca su questo

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

ISNULL è leggermente più ampio in quanto se è totalmente ridondante può essere ottimizzato e non impedire una ricerca.

cioè se la colonna Mod6è definita come NOT NULLallora quanto segue può produrre una ricerca.

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

Ma questo ovviamente non offre alcun vantaggio rispetto al solo fare

WHERE Mod6 = 0
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.