面试题:MySQL 中 count(*)、count(1) 和 count(字段名) 有什么区别?

在 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
喜欢就支持一下吧
点赞13 分享