MySQL中count(1)和count(*) 的区别
MySQL中count(1)和count(*) 的区别
在 MySQL 中,COUNT(1)
和 COUNT(*)
均用于统计查询结果中的行数,但它们在语义及其背后的机制上有一些区别。
基本功能
-
COUNT(*)
:统计表中所有行的数量,无论列是否为 NULL。 -
COUNT(1)
:统计所有行,这里的1
是一个常数表达式,表示每一行都会被计数。
在大多数情况下,COUNT(*)
和 COUNT(1)
的行为是完全一致的,它们都会返回表中的总行数。
区别
1. 语义和直观性
-
COUNT(*)
:-
语义上更清晰,表示“统计所有行”。
-
对于不了解 SQL 的人来说,更容易理解。
-
-
COUNT(1)
:-
看起来像是针对某一个具体值的计数,但其实
1
是一个常量,它并不依赖于表中的任何列。 -
可能会让一些人误以为它只统计某些符合条件的行(但实际上不是)。
-
2. 性能
-
在大多数现代数据库管理系统的优化下,
COUNT(*)
和COUNT(1)
的性能是相同的。-
数据库优化器通常会将两者视为等价的查询,并生成相同的执行计划。
-
例如,在 MySQL 中,执行以下两个查询时,它们的执行计划(
EXPLAIN
)是相同的:EXPLAIN SELECT COUNT(*) FROM users; EXPLAIN SELECT COUNT(1) FROM users;
-
-
但是,在某些极端情况下,可能会有一些微小的差别:
-
例如,在某些存储引擎中(如
MyISAM
),COUNT(*)
可能会直接读取存储的行数统计信息,而COUNT(1)
也可能会利用同样的优化机制。 -
如果表中存在大量数据,并且查询条件需要全表扫描,两者几乎没有性能差异。
-
3. 适用场景
-
COUNT(*)
:-
一般情况下,推荐使用
COUNT(*)
,因为它的语义更清晰,更容易让其他开发者理解查询的意图。
-
-
COUNT(1)
:-
在一些旧版本的数据库系统中,可能更倾向于使用
COUNT(1)
,但如今这种差异已经不明显。 -
如果需要统计行数,但希望保持代码的一致性,可以使用
COUNT(1)
,尤其是在代码中已经大量使用这种形式的情况下。
-
示例
假设有一个表 users
,包含以下数据:
id | name | age |
---|---|---|
1 | Alice | 25 |
2 | Bob | |
3 | Carol | 30 |
-
查询:
SELECT COUNT(*) FROM users;
结果:
3
-
查询:
SELECT COUNT(1) FROM users;
结果:
3
注意:
-
如果使用
COUNT(column_name)
,则只会统计该列非 NULL 的行数。例如:SELECT COUNT(age) FROM users;
结果:
2
(因为Bob
的age
是 NULL)。
总结
-
通常,
COUNT(*)
和COUNT(1)
是等价的,区别主要在于语义和代码风格。 -
推荐使用
COUNT(*)
,因为它更直观、语义明确。