在mySQL/SQL中,count(0),count(1)和count(*)有什么区别?

58

我最近在面试中被问到这个问题。 我尝试在MySQL中执行了这个操作,得到了相同的结果(最终结果)。 所有方法都可以得到特定表中行数的数量。 有人能解释一下它们之间的主要区别吗?


1
在一列中有一个 null 值。然后对该列进行计数。观察计数的差异。选择 01 只是为每行选择一个常量,不会涉及到 null - Glenn
可能是在SQL中,count(column)和count(*)有什么区别?的重复问题。 - newtover
9个回答

69

除非您在表中指定字段或括号内的表达式,否则不会发生任何事情,而不是常量值或 *。

让我给你一个详细的答案。Count将给出给定字段的非空记录数。假设您有一个名为A的表。

select 1 from A
select 0 from A
select * from A

所有查询将返回相同数量的记录,即表A中的行数。但输出是不同的。如果表中有3条记录,并且字段名为X和Y。

select 1 from A will give you

1
1
1

select 0 from A will give you
0
0
0

select * from A will give you ( assume two columns X and Y is in the table )
X      Y
--     --
value1 value1
value2 (null)
value3 (null)

所以,所有三个查询返回相同的数字。除非您使用


select count(Y) from A 

因为只有一个非空值,所以您将获得1作为输出


2
那么为什么在 count 函数中要传递整数值呢? - Dhruv
1
@DhruvSingh在我的回答中给了你更多的细节。 - Bren
1
@Felipe Correa 考虑到 Oracle,实际上没有任何性能差异,如果你获取执行计划,你会发现 Oracle 运行方式都是一样的。正如 eftpotrm 在他的回答中所说,过去可能不同,count(1) 或 count(0) 更可取。但现在我怀疑在任何 RDBMS 系统中都不会有区别。 - Bren
如果 A.XNULL,而 A.Y 也是 NULL,那么不清楚算什么。 - Victoria

51

COUNT(*)会计算行数,而COUNT(expression)会计算表达式中非空值的数量,COUNT(column)会计算列中所有非空值的数量。

由于0和1都是非空值,因此COUNT(0)=COUNT(1),它们都等同于行数的数量COUNT(*)。这是不同的概念,但结果将是相同的。


感谢fthiella。@brhneser为像我这样的初学者提供了更详细的答案。 - Dhruv
1
是的,你说得对,但我认为 count(*)count(1) 要花费更长的时间,不是吗?如果是的话,那么使用 count(1) 对于性能来说会更好。 :) - Yubaraj
4
“count(1)”曾经在某些数据库管理系统上比“count()”表现更好,但现在优化器能够使“count()”等同于“count(1)”。 - fthiella

19

现在-它们都应该表现出相同的效果。

然而,在过去的日子里,COUNT(1)(或您选择的任何常量)有时比COUNT(*)更受推荐,因为糟糕的查询优化代码会使数据库在运行计数之前检索所有字段数据。因此,COUNT(1)更快,但现在这不重要了。


6

由于表达式1是常量表达式,因此它们应该始终产生相同的结果,但是实现可能会有所不同,因为某些关系型数据库可能会检查每个组中的每一行是否1 IS NULL正如我在这篇文章中展示的那样,PostgreSQL 11.3仍然在执行此操作。

我已经对执行两种类型计数的100万行查询进行了基准测试:

-- Faster
SELECT count(*) FROM t;

-- 10% slower on PostgreSQL 11.3
SELECT count(1) FROM t;

使用不太直观的 COUNT(1) 的原因之一可能是历史上相反。


2

结果将是相同的,但是在许多生产环境中,COUNT(*)速度较慢,因为在生产中,数据库引擎可以存在几十年。我更喜欢使用COUNT(0),有些人使用COUNT(1),但绝对不使用COUNT(*),即使它在现代数据库引擎上是安全的,我也不会依赖于引擎,特别是如果只有一个字符的差异,此外,代码将更具可移植性。


1
  1. 使用count(any integer value)比使用count(*)更快 ---> 包括null值在内的所有计数都会被统计

  2. 使用count(column_name)将省略null值

例如-->

列名=> id

值 => 1 1 null null 2 2

==> count(0), count(1), count(*) -----> 结果为6

==> count(id) ----> 结果为4


0

假设我们有一个带有列的表格

Table 
-------
col_A  col_B

当我们查询时,系统返回所有列(包括空值和非空值)的值。

select col_A from Table

当我们查询时,系统返回非空的列值

select count(col_A) from Table

当我们查询时,系统会返回总行数

select count(*) from Table

0

Mysql5.6

InnoDB在处理SELECT COUNT(*)和SELECT COUNT(1)操作时采用相同的方式,没有性能差异。
官方文档是我找到许多不同答案后最快的途径。 12.19.1 聚合函数描述

-1
COUNT(*), COUNT(1) , COUNT(0), COUNT('Y') , ...

以上所有方法都返回记录的总数(包括空记录)。

但是COUNT('任意常量')COUNT(*)更快。


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