在 MySQL 中,COUNT(*)
、COUNT(1)
和 COUNT(字段名)
都是用于计算行数的聚合函数,但它们之间有一些细微的区别:
1. COUNT(*)
- 作用:计算表中所有行的数量,包括含有
NULL
值的行。 - 性能:MySQL 在执行
COUNT(*)
时进行了优化,它不会实际读取表中的数据行,而是直接使用存储引擎提供的快速路径来获取表的行数(对于某些存储引擎如 MyISAM 来说)。
而对于 InnoDB 存储引擎来说,由于其支持事务和 MVCC,可能需要扫描索引来计算行数,因此性能会根据具体情况有所不同。
2. COUNT(1)
- 作用:与
COUNT(*)
类似,COUNT(1)
也会计算表中所有行的数量。这里的1
可以被看作是一个常量表达式,对每一行都会返回一个值,因此也包括含有NULL
值的行。 - 性能:理论上,
COUNT(1)
的执行效率与COUNT(*)
相同或非常接近,因为 MySQL 优化器通常会将两者视为等价,并采用相同的执行计划。
3. COUNT(字段名)
- 作用:计算指定列中非
NULL
值的行数。如果该列存在NULL
值,则这些行不会被计入总数。 - 性能:如果
字段名
上有索引,那么COUNT(字段名)
可能会比COUNT(*)
更快,因为它只需要检查索引树而不需要访问完整的数据页。
但是,如果该列没有索引或者大多数值都不是NULL
,则性能可能与COUNT(*)
相当甚至更差,因为它可能需要额外的步骤来判断哪些行包含非NULL
值。
总结
- 使用
COUNT(*)
或COUNT(1)
来计算表中所有行的数量是最常见的方式,二者在性能上几乎无差异,选择哪一个主要取决于个人偏好或团队编码规范。 - 如果你需要统计某一特定列中非
NULL
值的数量,则应使用COUNT(字段名)
。 - 在实践中,除非你确实需要统计某个字段的非
NULL
值数量,否则推荐使用COUNT(*)
,因为它语义明确且性能最优。此外,避免不必要的复杂性也是编写高效 SQL 查询的重要原则之一。
THE END