我的一位开发人员争辩说,这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.
否
COALESCE
是不可分割的。您自己的测试很好地证明了这一点。
如果您使用
COALESCE
表达式创建了一个计算列并将其编入索引,则例外情况。您最终可能会对此进行搜索
ISNULL
稍微更可悲的是,如果它完全冗余,则可以对其进行优化,而不会阻止搜索。即,如果该列
Mod6
被定义为NOT NULL
那么以下可以产生一个搜索。但这当然不会比仅仅做