布尔等价

时间:2013-08-16 13:00:38

标签: sql-server sql-server-2012

我经常在ISNULL子句中使用COALESCEON但已经读过这会导致优化问题,因为索引可能无法使用。

我目前有以下内容:

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)

1 个答案:

答案 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