这段话总结了在不同场景下使用 COUNT(*)
、COUNT(1)
和 COUNT(列名)
的性能差异,虽然有些说法并不完全准确或依赖于数据库实现(如MySQL、Oracle等),但我们可以结合数据库原理和常见优化策略来分析其合理性与适用性。
表达式 | 含义 |
---|---|
COUNT(*) |
统计所有行数,包括NULL值的列。 |
COUNT(1) |
1 是常量表达式,每一行都为非 NULL,等价于 COUNT(*)。 |
COUNT(列名) |
统计该列中 非 NULL 的记录数。若该列为索引列(特别是主键)则更快。 |
列名为主键,
count(列名)
会比count(1)
快
COUNT(主键)
时,可以利用 主键索引 来快速统计行数。COUNT(1)
或 COUNT(*)
可能需要扫描整张表的数据页,即使它们逻辑上不需要访问数据本身。COUNT(主键)
确实可能比 COUNT(1)
更快,尤其是在有大量数据的情况下。✅ 结论:合理,适用于部分数据库(如MySQL)
列名不为主键,
count(1)
会比count(列名)
快
COUNT(列名)
需要检查每一行该列是否为 NULL。COUNT(1)
是常量表达式,无需检查列值是否为空。COUNT(1)
性能通常优于 COUNT(列名)
。✅ 结论:合理,适用于大多数数据库
如果表多个列并且没有主键,则
count(1)
的执行效率优于count(*)
COUNT(*)
和 COUNT(1)
实际上被优化成完全相同的执行计划。COUNT(1)
可能会被认为更“轻量”,因为它显式指定了一个表达式而非整个行。⚠️ 结论:不一定成立,取决于具体数据库实现。多数现代数据库中两者性能相同。
如果有主键,则
select count(主键)
的执行效率是最优的
COUNT(主键)
可以利用索引来加速统计。✅ 结论:合理,尤其在 MySQL 中表现明显
如果表只有一个字段,则
select count(*)
最优
COUNT(*)
直接统计行数,逻辑清晰,且数据库优化器容易识别为最简单路径。COUNT(列名)
会慢于 COUNT(*)
。✅ 结论:合理
场景 | 推荐写法 | 说明 |
---|---|---|
想统计总行数,不管是否有 NULL | COUNT(*) |
语义明确,数据库优化好 |
有主键,想提高性能 | COUNT(主键) |
可利用索引,速度最快 |
无主键,列名含 NULL | COUNT(1) |
避免判断 NULL,性能稳定 |
明确只想统计某列非 NULL 数量 | COUNT(列名) |
语义正确 |
多列且无主键 | COUNT(*) 或 COUNT(1) |
性能几乎一致 |
COUNT(*)
和 COUNT(1)
几乎一样,COUNT(主键)
最快。COUNT(*)
内部转换为 COUNT(1)
,性能一致。观点 | 是否合理 | 说明 |
---|---|---|
COUNT(主键) > COUNT(1) |
✅ | 主键可利用索引,速度快 |
COUNT(1) > COUNT(列名) |
✅ | 非主键列需判断 NULL |
COUNT(1) > COUNT(*) |
⚠️ | 多数情况不成立,取决于数据库 |
COUNT(主键) 最优 |
✅ | 特别适合 MySQL |
单列表用 COUNT(*) 最优 |
✅ | 语义清晰,数据库优化好 |