在使用join时,count(*)和count(1)的区别
在使用join时,count(*)和count(1)的区别
我想知道你们有没有使用Count(1)
替代Count(*)
,并且是否存在明显的性能差异,或者这只是过去的习惯传承下来的?
具体数据库是SQL Server 2005
。
admin 更改状态以发布 2023年5月22日
在SQL Server中,这些语句会产生相同的计划。
与通行的观点不同,在Oracle中也是如此。
SYS_GUID()
在Oracle中是计算强度很高的函数。
在我的测试数据库中,t_even
是一个有1,000,000
行的表。
这个查询:
SELECT COUNT(SYS_GUID()) FROM t_even
需要运行48
秒,因为函数需要评估每个返回的SYS_GUID()
,以确保它不是NULL
。
然而,这个查询:
SELECT COUNT(*) FROM ( SELECT SYS_GUID() FROM t_even )
仅需2
秒,因为它甚至不尝试评估SYS_GUID()
(尽管*
是COUNT(*)
的参数)
没有区别。
原因:
在线图书 中写到"
COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )
"
"1"是一个非空表达式:所以它与COUNT(*)
相同。
优化器识别它是微不足道的东西。
与EXISTS (SELECT * ...
或EXISTS (SELECT 1 ...
相同
例子:
SELECT COUNT(1) FROM dbo.tab800krows SELECT COUNT(1),FKID FROM dbo.tab800krows GROUP BY FKID SELECT COUNT(*) FROM dbo.tab800krows SELECT COUNT(*),FKID FROM dbo.tab800krows GROUP BY FKID
相同的IO、相同的计划,一切都一样
2011年8月编辑
2011年12月编辑
COUNT(*)
在ANSI-92中有明确提到(查找"Scalar expressions 125
")
情况:
a) 如果指定了COUNT(*),则结果是T的基数。
也就是说,ANSI标准认为你的意思是非常明显的。由于这种迷信,RDBMS供应商已经优化掉了COUNT(1)
。否则,它将按照ANSI进行评估
b) 否则,让TX成为将
应用于T的每一行并消除空值后的单列表。如果消除了一个或多个空值,则会引发完成条件:警告-