MySQL 中 count(*)、count(1) 和 count(字段名) 有什么区别?
🔍 COUNT(*)
✅ 统计表中所有行数(包括 NULL
值)
COUNT(*)
会统计表中的 所有行,不会忽略NULL
值。- 其底层实现会遍历整个表,但不会具体读取字段,而是由 存储引擎优化 来获取行数。
- 在 InnoDB 中,
COUNT(*)
会利用 聚簇索引 进行优化,性能通常较高。
🔍 COUNT(1)
✅ 统计表中所有行数(包括 NULL
值)
COUNT(1)
会统计 所有行,不会忽略NULL
值,与COUNT(*)
类似。- 它的计算方式是把
1
作为一个常量,然后遍历整张表并对行数进行累加。 - 性能上一般与
COUNT(\*)
接近,但COUNT(*)
在 MySQL 经过了更多优化,因此通常优先选择COUNT(*)
。 - 注意:
COUNT(2)
的行为与COUNT(1)
完全相同,它会统计 所有行的数量,包括NULL
值。
🔍 COUNT(字段名)
✅ 统计该字段 非 NULL
的行数
- 区别于
COUNT(\*)
和COUNT(1)
,COUNT(字段名)
仅统计 该字段不为NULL
的行。 - 如果某个字段存在
NULL
值,这些NULL
值的行不会被统计。 - 性能取决于是否使用索引:
- 如果
字段名
是 非空字段(NOT NULL),COUNT(字段名)
与COUNT(*)
结果相同。 - 如果
字段名
存在NULL
值,统计结果会小于COUNT(*)
。
- 如果
📊 性能比较
方式 | 统计范围 | NULL 处理 | 适用场景 | 性能 |
---|---|---|---|---|
COUNT(*) | 所有行 | 统计 NULL 行 | 统计总行数(推荐) | 最快(InnoDB 经过优化) |
COUNT(1) | 所有行 | 统计 NULL 行 | 统计总行数 | 一般等同于 COUNT(*) |
COUNT(字段名) | 非 NULL 行 | 忽略 NULL 行 | 统计特定字段的非空值 | 可能较慢(取决于索引) |
🎯 最佳实践
- 如果要统计表中的总行数,使用
COUNT(*)
,因为 MySQL 针对它做了优化,特别是在 InnoDB 里。 COUNT(字段名)
适用于需要排除NULL
值的情况,比如统计某个字段的实际填写数量。