IsNULL和Coalesce正确使用

时间:2012-05-19 19:16:37

标签: asp.net sql-server-2008 sql-server-2005

因为我们有两个选项来拦截来自数据库的空值......

  
      
  1. ISNULL
  2.   
  3. 聚结
  4.   

以下是为上述两个函数编写查询的方法......

Select IsNull(Columnname, '') As validColumnValue From TableName

Select Coleasce(Columnname, '') As validColumnValue From TableName

查询 - 哪种情况应该优先选择?为什么?

3 个答案:

答案 0 :(得分:5)

这已被哈希并重新散列。除了the tip I pointed out in the comment以及上面发布的@xQbert链接和解释之外,这里的请求是使用子查询对COALESCE与ISNULL的解释。让我们考虑这两个查询,这些查询在结果方面是相同的:

SELECT COALESCE((SELECT TOP (1) name FROM sys.objects), N'foo');

SELECT ISNULL((SELECT TOP (1) name FROM sys.objects), N'foo');

(关于在没有ORDER BY的情况下使用TOP到/ dev / null / thanks的评论。)

在COALESCE案例中,逻辑实际上扩展到如下:

SELECT CASE WHEN (SELECT TOP (1) ...) IS NULL
    THEN (SELECT TOP (1) ...)
    ELSE N'foo'
END

使用ISNULL,这不会发生。有一个内部优化似乎确保子查询只被评估一次。我不知道微软以外的人是否知道这种优化的确切方式,但如果你比较计划,你可以这样做。以下是COALESCE版本的计划:

enter image description here

这是ISNULL版本的计划 - 注意它的简单程度(并且扫描只发生一次):

enter image description here

在COALESCE情况下,扫描发生两次。这意味着子查询被评估两次,即使它没有产生任何结果。如果添加WHERE子句以使子查询产生0行,您将看到类似的差异 - 计划形状可能会发生变化,但您仍会看到双重搜索+查找或扫描COALESCE情况。这是一个略有不同的例子:

SELECT COALESCE((SELECT TOP (1) name FROM sys.objects 
    WHERE name = N'no way this exists'), N'foo');

SELECT ISNULL((SELECT TOP (1) name FROM sys.objects 
    WHERE name = N'no way this exists'), N'foo');

这次是COALESCE版本的计划 - 再次你可以看到代表子查询的整个分支一再重复:

enter image description here

再一个更简单的计划,大约一半的工作,使用ISNULL:

enter image description here

您还可以在dba.se上查看此问题,以获得更多讨论:

https://dba.stackexchange.com/questions/4274/performance-difference-for-coalesce-versus-isnull

我的建议就是这个(你可以在小费和上面的问题中看到我的原因):信任但要验证。我总是使用COALESCE(因为它是ANSI标准,支持两个以上的参数,并且不会像数据类型优先级那么糟糕)除非我知道我使用子查询作为其中一个表达式(我不记得曾经在这样的理论工作之外做过)或者我遇到了一个真正的性能问题,只是想比较看看COALESCE和ISNULL是否有任何实质性的性能差异(在子查询案例之外,我还没有找到)。由于我几乎总是使用COALESCE与类似数据类型的参数,我很少做任何测试,除了回顾过去我曾经说过的内容(我也是the aspfaq article that xQbert pointed out的作者,7几年前)。

答案 1 :(得分:1)

开始幽默 :第1名,第2名将永远无法正常拼错:D END幽默 < / p>

---清理回应---

isNull(value1,value2)

的功能
  • 只支持1个评估,如果第一个为null,则使用第2个,所以如果它也为null,则返回null!
  • 是非ANSI标准。意味着如果数据库可移植性是一个问题,请不要使用此
  • isnull(value1,value2)将返回Value1
  • 的数据类型
  • 将返回所选值的数据类型,并且在无法进行隐式转换时失败

合并的功能(Value1,Value2,value3,value ...)

  • 支持Null的多次估值;基本上将从列表中拉入第一个非空值。如果列表中的所有值都为null,则返回null。
  • 是ANSI标准,意味着数据库可移植性应该不是问题。
  • 将返回所选值的数据类型,如果select中的所有字段都不返回相同的数据类型,则会失败。

所以直接回答这个问题: 如果你需要开发SQL

,这取决于具体情况
  • 与DB无关; coalesce使用起来更正确。
  • 允许多次评估; coalesce更正确(当然你可以一次又一次地嵌入isnull ......)但是把它放在性能显微镜下,并且合并可能会赢。 (我没有测试过它)
  • 您使用的是支持isNull的数据库引擎吗? (如果不使用合并)
  • 你想怎么处理类型铸造?隐含或不含。

--- ------ ORIGINAL 为null仅支持2次评估

coalesce支持更多... coalesce(columnName1,ColumnName2,ColumnName3,'')

coalesce返回类似于case评估的数据类型,而isnull返回list中first的数据类型。 (我觉得很有趣!)

何时使用哪个。你必须通过查看SQL 2008和2005两者的执行计划来调查,不同版本的不同引擎有不同的执行方式。

此外,合并是ansii标准,isnull是引擎特定的。因此,如果您希望dbengines之间具有更大的可移植性,请使用coalesce。

更多信息here aspfaqhere msdn blog

答案 2 :(得分:0)

你可以考虑这个。

  1. ISNULL 函数需要两个参数:要检查的值和替换空值

    2. COALESCE 功能有点不同 COALESCE 将采用任意数量的参数并返回第一个非 NULL 值,我更喜欢 COALESCE 超过 ISNULL '原因 符合 ANSI 标准,而 ISNULL 则不符合。

    我希望你找到了问题的答案。