COALESCE和ISNULL哪个更快?

30

我知道这些函数的区别,但我的问题是在检查单个空值时,使用 ISNULL 是否比使用 COALESCE 更快?

例如:

COALESCE(SELECT TOP 1 SomeValue FROM SomeTable, 0)

对比

ISNULL(SELECT TOP 1 SomeValue FROM SomeTable, 0)
6个回答

15

看了一下这个问题,因为看到有很多不同的比较关于它们之间性能的文章。我认为Adam Machanic在他的博客文章中对这个问题所做的性能基准测试最准确,底线是:

... 而ISNULL似乎比COALESCE表现得更出色,在平均值上高出10或12%

然而,我与他接下来所说的观点相同 - 差异是相当微不足道的 - 例如,在他的测试中,一百万次执行的平均差距只有0.7秒。值得吗?我建议可能有更大的优化空间。但是请阅读这篇文章,这很有意思。


2
我的投票是支持“这值得吗?我建议可能有更大的优化领域”这句话说得很对。 - Tejasvi Hegde
2
“但这就是6秒和5.3秒之间的区别” - 说实话,至少在他的简单例子中,我认为这是相当显著的。 - AaronHolland

11
在这种情况下,ISNULL是最佳选择。因为SQL Server将COALESCE函数解释为CASE语句。所以,你的查询
COALESCE(SELECT TOP 1 SomeValue FROM SomeTable, 0)
将被SQL Server写成
CASE WHEN (SELECT TOP 1 SomeValue FROM SomeTable) IS NOT NULL THEN (SELECT TOP 1 SomeValue FROM SomeTable) ELSE 0 END
如果你观察上述解释,“SomeTable”将被扫描两次。但是ISNULL将只被评估一次。

有一个Microsoft Connect问题,涉及COALESCE运算符对相同查询进行两次评估的问题。 - Aaroninus

3

ISNULL会更快,因为它本身的函数/代码实现较少,使其比COALESCE更快。


1

第一个链接说要优先使用ISNULL,而第二个链接建议优先使用COALESCE! - AdaTheDev
性能:ISNULL vs. COALESCE http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/performance-isnull-vs-coalesce.aspx - amexn
最后一个链接已经失效。 - Gun2sh

0

就其价值而言,你有一个非常具体的用例,因此我在脑海中想到一个表格的第一个in值上使用了你实际问题的样例,并为其他变量控制了脚本。我假设someval是一个整数,因为你使用了0。我的建议是,你选择你特定的someval/sometable情况,并自己进行测试。

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);

结果相当惊人,isnull的计算时间为11270,而coalesce则需18930。将循环顺序颠倒再测试一次后,coalesce的计算时间为18260,isnull则只需10810。对于你的具体情况而言,我认为isnull明显更快。

这并不代表在其他情况下isnull就更好。使用简单值、nvarchars或位(bit)而非int,或者列不是主键,或将isnull嵌套与向coalesce添加参数进行比较等等都可能改变计算结果。

这仅回答了所提出的问题。


-4

我刚刚在自己的数据库上进行了测试。大约有70万行数据。

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

在56秒内获得12106的结果。

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
@Fraser 嗯,确实。我可能会用 WHERE !ISNULL(field_1)... 重新运行测试。但是我们难道不能相当确定调用 ISNULL() 函数的速度甚至比使用 IS NOT NULL 还要慢吗? - Buttle Butkus
这不是 ISNULL 的工作方式,也不是你使用 ISNULL 函数的方式。请参阅 https://learn.microsoft.com/en-us/sql/t-sql/functions/isnull-transact-sql。 - herostwist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接