Apakah COALESCE bisa digunakan sekarang?

9

Salah satu pengembang saya berpendapat bahwa COALESCE(column, default value) = default valuesekarang cukup murah. Apakah itu benar?

Saya menjalankan tes berikut, dan berpikir itu menyiratkan bahwa COALESCEitu tidak dapat ditawar.

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.
Mitch
sumber
5
Apakah pengembang Anda berdebat dengan bukti apa pun?
Aaron Bertrand
Saya membaca posting ini: josef-richberg.squarespace.com/journal/2010/1/28/... Saya tidak berpikir bahwa jawaban konkret dapat diturunkan untuk menjawab posting ini. (Tapi mungkin orang lain lebih tahu.)
RLF
@ RRL - artikel itu tidak mengatakan apa pun yang akan menunjukkan bahwa itu pantas. Ini bukan demonstrasi bahwa itu pantas. twitpic.com/107ms0 . Non sargability adalah bahwa ia mencegah pencarian pada kolom yang digunakan dalam CASEekspresi - bukan bahwa hasil dari ekspresi tidak dapat digunakan untuk mencari sesuatu yang lain.
Martin Smith
@AaronBertrand, "Rencana eksekusi tampak sama tidak peduli bagaimana saya menulisnya" - Dia mengabaikan fakta bahwa tidak ada yang melakukan pencarian berdasarkan COALESCEkolom d.
Mitch
1
Oh, saya tidak menyalahkan Anda karena mengajukan pertanyaan, terutama karena Anda berusaha untuk membantahnya terlebih dahulu. Saya hanya menyarankan agar pengembang Anda harus belajar melakukan hal yang sama.
Aaron Bertrand

Jawaban:

15

Tidak, COALESCEtidak sargable.

Tes Anda sendiri menunjukkan ini dengan baik.

Pengecualian akan terjadi jika Anda membuat kolom yang dihitung dengan COALESCEekspresi dan mengindeksnya.

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

Anda bisa berakhir dengan mencari itu

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

ISNULL sedikit lebih mahal dalam hal itu jika benar-benar berlebihan itu dapat dioptimalkan dan tidak mencegah pencarian.

yaitu jika kolom Mod6didefinisikan sebagai NOT NULLmaka berikut ini dapat menghasilkan pencarian.

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

Tetapi ini tentu saja tidak memberikan manfaat apa pun dari sekadar melakukan

WHERE Mod6 = 0
Martin Smith
sumber