只是想知道你们中是否有人使用Count(1)而不是Count(*),是否在性能上有明显的差异,或者这只是过去几天养成的传统习惯?

特定的数据库是SQL Server 2005。


当前回答

COUNT(*)和COUNT(1)在结果和性能方面是相同的。

其他回答

有一篇文章显示,Oracle上的COUNT(1)只是COUNT的别名(*),并提供了相关证据。

我将引用一些部分:

数据库软件的一部分叫做“Optimizer”,在官方文档中定义为“内置数据库软件,可确定执行SQL语句”。优化器的一个组件叫做“变压器”,其作用是确定重写将原始SQL语句转换为语义等价的SQL语句这可能更有效。您想看看优化器在编写查询时做什么吗使用COUNT(1)?

对于具有ALTER SESSION权限的用户,您可以放置tracefile_identifier,启用优化器跟踪并运行COUNT(1)select,例如:select/*test-1*/COUNT(1,FROM employees;。

之后,您需要本地化跟踪文件,这可以通过SELECT VALUE FROM V$DIAG_INFO WHERE NAME='DIAG trace';来完成;。稍后在文件中,您将发现:

SELECT COUNT(*) “COUNT(1)” FROM “COURSE”.”EMPLOYEES” “EMPLOYEES”

如您所见,它只是COUNT(*)的别名。

另一个重要的评论是:20年前,在Oracle 7.3之前,COUNT(*)确实更快:

自7.3以来,计数(1)已重写为计数(*),因为Oracle类似自动调整mythic语句。在早期的Oracle7中,oracle必须在确定之前对每一行求值(1),作为函数存在非确定性。20年前,count(*)更快

对于另一个数据库(如SqlServer),应分别对每个数据库进行研究。

我知道这个问题是针对SQL Server的,但SO中关于同一主题的其他问题(没有提到特定的数据库)已关闭,并标记为与此答案重复。

没有区别。

原因:

在线书籍说“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月

DBA.SE上的类似问题。

编辑,2011年12月

ANSI-92中特别提到了COUNT(*)(查找“标量表达式125”)

案例:a) 如果指定了COUNT(*),则结果是T的基数。

也就是说,ANSI标准认为这是你的意思。由于这种迷信,RDBMS供应商已经优化了COUNT(1)。否则将按照ANSI进行评估

b) 否则,让TX是单列表,即将<value表达式>应用于T的每一行的结果以及消除空值。如果一个或多个空值消除,则引发完成条件:警告-

在所有RDBMS中,这两种计数方式在产生什么结果方面是等价的。关于性能,我没有在SQL Server中观察到任何性能差异,但值得指出的是,一些RDBMS,例如PostgreSQL 11,在检查参数表达式的可空性时,COUNT(1)的实现不太理想,如本文所示。

我发现运行以下命令时,1M行的性能差异为10%:

-- Faster
SELECT COUNT(*) FROM t;

-- 10% slower
SELECT COUNT(1) FROM t;

在SQL Server中,这些语句产生相同的计划。

与流行的观点相反,在甲骨文公司,他们也是如此。

Oracle中的SYS_GUID()是一个计算密集型函数。

在我的测试数据库中,t_even是一个包含1000000行的表

此查询:

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(*)和COUNT(1)将始终返回相同的结果。因此,如果一个比另一个慢,这实际上是由于优化器错误。由于这两种形式在查询中都使用得非常频繁,所以DBMS不允许这样的错误保持不变是没有意义的。因此,您将发现两种形式的性能(可能)在所有主要的SQL DBMS中都是相同的。