1

我经常使用ISNULLand COALESCEin子句,但读到这可能会导致优化问题,因为索引可能不会被使用。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

这些是等价的吗?
如果不是,那为什么不呢?


编辑
我不是 100% 认为它可能会影响性能,但最近我读了 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)

4

1 回答 1

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 
于 2013-08-16T13:04:45.777 回答