COALESCE şimdi anlaşılabilir mi?


9

Geliştiricilerimden biri, COALESCE(column, default value) = default valuebunun artık çirkin olduğunu savunuyor. Bu doğru mu?

Aşağıdaki testi yaptım ve bunun COALESCEçirkin olmadığını ima ettiğini düşünüyorum .

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
Geliştiriciniz herhangi bir kanıtla tartıştı mı?
Aaron Bertrand

Bu yazıyı okudum: josef-richberg.squarespace.com/journal/2010/1/28/… Ben bu yazıyı cevaplamak için somut bir cevap türetilebilir sanmıyorum. (Ama belki başka biri daha iyisini bilir.)
RLF

@RLF - bu makale anlaşılabilir olduğunu belirten bir şey söylemiyor. Bu anlaşılabilir bir gösteri değil. twitpic.com/107ms0 . Uyumsuzluk, CASEifadede kullanılan sütunlarda bir aramayı engellemesidir - ifadenin sonucunun daha sonra başka bir şey aramak için kullanılamaz.
Martin Smith

@AaronBertrand, "Nasıl yazılırsa uygulansın planı aynı görünüyordu" - İkisinin de COALESCEd sütununa dayalı bir arama yapmadığı gerçeğini göz ardı etti .
Mitch

1
Oh, özellikle soruyu ilk önce çürütmeye çalıştığınız için, soruyu sormakla suçlamıyorum. Sadece geliştiricinizin de aynısını yapmayı öğrenmesi gerektiğini söylüyordum.
Aaron Bertrand

Yanıtlar:


15

Hayır COALESCEanlaşılmaz değil.

Kendi testiniz bunu iyi gösteriyor.

COALESCEİfade ile hesaplanan bir sütun oluşturup dizine eklerseniz istisna olur .

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

Bu konuda bir arama ile sonuçlanabilir

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

ISNULL tamamen yedekli ise optimize edilebilir ve bir aramayı engellemeyeceği için marjinal olarak daha anlaşılır.

yani sütun Mod6şöyle tanımlanırsa NOT NULLaşağıdakiler bir arama üretebilir.

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

Ama bu elbette sadece yapmaktan başka bir fayda sağlamaz

WHERE Mod6 = 0
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.