select count(1) as male_num
,round(avg(gpa),1) as avg_gpa
from user_profile
where gender = 'male';
COUNT(*)和COUNT(1)几乎完全一样(统计所有行,包含 NULL),现代数据库中性能无差别。COUNT(字段)不一样(只统计该字段不为 NULL 的行)。
COUNT(*) vs COUNT(1):到底哪个快?
在早期的数据库版本(如旧版 MySQL MyISAM 引擎)中,有人认为 COUNT(1) 比 COUNT(*) 快,因为 * 需要解析所有列。
但在现代数据库(MySQL 5.7/8.0+, PostgreSQL, Oracle, SQL Server)中:
- 优化器智能处理:数据库优化器非常聪明,它发现你只是要计数,根本不会去读取具体的列数据。
- 执行计划一致:查看
EXPLAIN执行计划,你会发现COUNT(*)和COUNT(1)生成的执行计划完全一模一样。 - 结论:性能没有区别。
最佳实践建议:
- 推荐使用
COUNT(*)。 - 原因:这是 SQL 标准写法,语义最清晰(“我要统计行数”),可读性最好。
COUNT(1)显得有点多余且带有“过度优化”的老旧味道。
特殊场景:COUNT(DISTINCT 字段)
还有一个变体是 COUNT(DISTINCT 字段):
- 规则:统计该字段非 NULL 且 不重复 的值个数。
- 性能:通常比普通的
COUNT慢,因为它需要进行去重排序或哈希操作。
总结建议
- 统计总行数:无脑用
COUNT(*)。 - 统计某列有效数据量(排除空值):用
COUNT(字段名)。 - 统计某列不重复的有效数据量:用
COUNT(DISTINCT 字段名)。 - 不要纠结
COUNT(1):它和COUNT(*)一样,但COUNT(*)更标准。

京公网安备 11010502036488号