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

特定的数据库是SQL Server 2005。


当前回答

随着这个问题一次又一次地出现,这里还有一个答案。我希望在这里为初学者添加一些关于“最佳实践”的内容。

SELECT COUNT(*)FROM something计数记录,这是一项简单的任务。

SELECT COUNT(1)FROM从某个对象中检索每条记录的1,然后对不为空的1进行计数,这实际上是对记录进行计数,只是更复杂。

话虽如此:好的dbms注意到,第二条语句将产生与第一条语句相同的计数,并相应地重新解释它,以免做不必要的工作。因此,通常这两个语句将产生相同的执行计划,并花费相同的时间。

但是,从可读性的角度来看,您应该使用第一条语句。您要计算记录,所以要计算记录而不是表达式。仅当您希望计算某个事件的非空出现时,才使用COUNT(表达式)。

其他回答

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

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

-- Faster
SELECT COUNT(*) FROM t;

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

在SQL-92标准中,COUNT(*)特别表示“表表达式的基数”(可以是基表、`VIEW、派生表、CTE等)。

我认为COUNT(*)很容易解析。使用任何其他表达式都需要解析器确保它不引用任何列(COUNT('a'),其中a是文本,COUNT(a),如果a是列,可以产生不同的结果)。

同样,COUNT(*)可以由熟悉SQL标准的程序员轻松识别,这是一种在使用多个供应商的SQL产品时非常有用的技能。

此外,在特殊情况下,SELECT COUNT(*)FROM MyPersistedTable;,其思想是DBMS可能保存表基数的统计信息。

因此,因为COUNT(1)和COUNT(*)在语义上是等价的,所以我使用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月

DBA.SE上的类似问题。

编辑,2011年12月

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

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

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

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

我希望优化器能够确保在奇怪的边缘情况之外没有真正的差异。

与任何事情一样,唯一真正的方法就是衡量你的具体情况。

也就是说,我一直使用COUNT(*)。

随着这个问题一次又一次地出现,这里还有一个答案。我希望在这里为初学者添加一些关于“最佳实践”的内容。

SELECT COUNT(*)FROM something计数记录,这是一项简单的任务。

SELECT COUNT(1)FROM从某个对象中检索每条记录的1,然后对不为空的1进行计数,这实际上是对记录进行计数,只是更复杂。

话虽如此:好的dbms注意到,第二条语句将产生与第一条语句相同的计数,并相应地重新解释它,以免做不必要的工作。因此,通常这两个语句将产生相同的执行计划,并花费相同的时间。

但是,从可读性的角度来看,您应该使用第一条语句。您要计算记录,所以要计算记录而不是表达式。仅当您希望计算某个事件的非空出现时,才使用COUNT(表达式)。