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(*),因为它更直观、语义明确。
