我经常在ISNULL
子句中使用COALESCE
和ON
但已经读过这会导致优化问题,因为索引可能无法使用。
我目前有以下内容:
FROM dbo.tb_xxx x
INNER JOIN dbo.tb_yyy y ON
x.Client = COALESCE(y.Client, x.Client) AND
x.Prod = COALESCE(y.Prod, x.Prod)
......我已转换为以下内容......
FROM dbo.tb_xxx x
INNER JOIN dbo.tb_yyy y ON
x.Client = y.Client AND
x.Prod = y.Prod
OR y.Client IS NULL
OR y.Prod IS NULL
这些是等价的吗? 如果没有,那为什么不呢?
修改
我不是百分之百,它可能会影响性能,但最近我读了Itzik Ben-Gan的一篇文章,其中指出在加入数据集时使用像COALESCE(T1.col1,-1) = COALESCE(T2.col1,-1)
这样的谓词会影响性能,因为col1的操作意味着重建数据并且不会使用col1上的现有索引。这就是“sargability”的概念。
而不是使用此匹配谓词
COALESCE(T1.col1,-1) = COALESCE(T2.col1,-1)
他建议这一点
T1.col1 = T2.col1 OR (T1.col1 IS NULL AND T2.col1 IS NULL)
答案 0 :(得分:4)
不,他们不是。
你所写的内容相当于
(x.Client = y.Client AND x.Prod = y.Prod)
OR (y.Client IS NULL)
OR (y.Prod IS NULL)
你需要
(x.Client = y.Client OR y.Client IS NULL)
AND
( x.Prod = y.Prod OR y.Prod IS NULL)
而且我不确定那会比原版更好。
关于性能问题,在SQL Server上,ISNULL
的性能通常优于COALESCE
,但后者符合ANSI标准,如果这对您很重要。
所以在我看来,你可能会尝试左联盟?
FROM dbo.tb_xxx x
LEFT JOIN dbo.tb_yyy y ON
x.Client = y.Client AND
x.Prod = y.Prod