2010-02-18 59 views
21

我明白这些函数之间的区别,但我的问题是检查单个null值ISNULL会比使用COALESCE更快吗?哪个更快合并或ISNULL?

COALESCE(SELECT TOP 1 SomeValue FROM SomeTable, 0) 

VS

ISNULL(SELECT TOP 1 SomeValue FROM SomeTable, 0) 

回答

3

ISNULL会更快我想是因为它有自身较小的功能/代码实现使得它比COALESCE

1

更快请检查链接 如果给出的选择是ISNULL倾向于更喜欢ISNULL而不是COALESCE生成比COALESCE更高效的查询计划。

  1. ISNULL Vs COALESCE

  2. ISNULL vs COALESCE speed test

  3. 请检查性能ISNULL vs. COALESCE

+0

第一个链接表示首选ISNULL,第二个链接表示COALESCE应该是首选! – AdaTheDev 2010-02-18 10:05:07

+0

请检查链接 表现:ISNULL与COALESCE http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/performance-isnull-vs-coalesce.aspx – amexn 2010-02-18 10:15:32

11

有一个快速浏览,因为它是有趣的,看看有关的性能之间的2个不同的比较2。我认为this由Adam Machanic博客文章是最准确的性能基准对此主题完成,其中底线是:

...和ISNULL显得相当 一贯 在性能COALESCE的10%或12%的平均

不过,我也有同感,他又是什么继续说 - 差异是可以忽略的 - 例如在他的测试中,一百万处决平均出现0.7秒的差异。这值得么?我建议可能有更大的领域需要优化。但阅读文章,这是一个很好的阅读。

+2

我的投票结果为“是吗?值得吗?我建议有可能有更大的领域来优化“真正的说。 – 2014-06-27 11:30:58

+0

“但是,这是6秒和5.3秒之间的差异” - 我会说这是非常重要的说实话,至少在他的微不足道的例子。 – AaronHolland 2018-02-07 22:37:15

6

在这种情况下,ISNULL是最佳选择。因为,SQL Server将COALESCE函数解释为CASE语句。所以,你的查询

COALESCE(SELECT TOP 1 someValue中FROM SomeTable,0)

会由SQL Server写成

  1. CASE
  2. WHEN(SELECT TOP 1 someValue中FROM SomeTable )IS NOT NULL
  3. THEN(SELECT TOP 1 SomeValue FROM SomeTable
  4. ELSE 0
  5. END

如果您遵守上述解释, “SomeTable” 将被扫描两次。但是ISNULL只会被评估一次。

+0

有关COALESCE运算符两次评估相同查询的开放[Microsoft Connect问题](https://connect.microsoft.com/SQLServer/feedback/details/336002/unnecessarily-bad-performance-for-coalesce-subquery) 。 – Aaroninus 2015-07-07 13:42:37

-2

我刚刚在我自己的数据库上运行测试。大约700k行。

SELECT COUNT(*) FROM table WHERE COALESCE(field_1,field_2,field_3,field_4) IS NOT NULL 

12106的结果在56秒内获得。

SELECT COUNT(*) FROM table WHERE field_1 IS NOT NULL OR field_2 IS NOT NULL OR field_3 IS NOT NULL OR field_4 IS NOT NULL 

在0.00秒内获得的12106的结果。

+2

不测试isnull()函数 – user314321 2015-11-17 00:50:53

+0

@Fraser hmmm,true。我可能会用'WHERE!ISNULL(field_1)...'重做测试。但我们不能确定函数调用ISNULL()会比使用“IS NOT NULL”更慢吗? – 2015-11-17 01:06:47

0

对于它的价值你有一个非常具体的用例,所以我使用了一个实际问题的示例,它首先出现在想到的表上,并控制了其他变量的脚本。我认为someval是你使用0时的一个int。我的建议是,你选择你的特定的someval/sometable case并自己做测试。

declare @val int = 0; 
declare @time1 Datetime2 = getdate(); 
declare @time2 Datetime2 = getdate(); 
Select @time1 = GETDATE(); 
while @MyCounter < 1000000 
Begin 
Select @val = ISNULL((SELECT TOP 1 LocationID FROM location), 0) 
Select @MyCounter +=1; 
END 
Select @time2 = GETDATE(); 
Print datediff(millisecond,@time1,@time2); 
Select @MyCounter = 0; 
Select @time1 = GETDATE(); 
while @MyCounter < 1000000 
Begin 
Select @val = COALESCE((SELECT TOP 1 LocationID FROM Location), 0) 
Select @MyCounter +=1; 
END 
Select @time2 = GETDATE(); 
Print datediff(millisecond,@time1,@time2); 

结果是非常戏剧性的,11270为isnull和18930为coalesce。作为第二次测试,将循环顺序颠倒,产生18260合并和10810 isnull。对于你的特定情况我会说isnull显然更快。

这并不是说在任何其他特定情况下它都会更好。直接使用值,或者nvarchar或者bit而不是int,或者不是主键的列,或者嵌套isnull与向coalesce添加参数可能会改变事情。

这只能解决问题。