COALESCE现在可燃了吗?


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,“无论我如何编写,执行计划看起来都是相同的”-他忽略了一个事实,即没有人执行基于COALESCEd列的查找。
米奇

1
噢,我不会怪您问这个问题,尤其是因为您首先试图反驳它。我只是建议也许您的开发人员应该学习做同样的事情。
亚伦·伯特兰

Answers:


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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.