COUNT(*)
和 COUNT(1)
是常用的统计函数,用于计算结果集中行的数量。功能非常相似,但在性能和实现细节上有一些区别。
一. COUNT(*) 的特点
- 功能:统计结果集中所有行的总数,包括值为
NULL
的行。 - 实现:
- 数据库在执行
COUNT(*)
时,并不会关心表中的具体列,而是统计所有行数。 - 数据库会对
COUNT(*)
做特殊优化,因为它是最常用的统计操作,执行时会直接使用表中的元信息(如行数的记录)。
- 数据库在执行
- 优点:
- 语义直观,通用性强。
- 在标准 SQL 中是首选,几乎所有数据库系统都支持。
- 缺点:
- 如果表设计不规范,或者没有优化引擎支持,可能会带来额外的开销。
二. COUNT(1) 的特点
- 功能:统计结果集中所有行的总数,但本质上与
COUNT(*)
的结果相同。 - 实现:
- 数据库会将
1
视为一个常量,作为一个伪列,每行都会生成一个值为1
的伪列。 - 然后统计这个伪列的非 NULL 值的数量。
- 数据库会将
- 优点:
- 一些旧版本的数据库(尤其是 MySQL 较早版本)中,
COUNT(1)
被认为可能比COUNT(*)
更高效,因为它不需要检查具体列。 - 在特定情况下,如果数据库系统对
COUNT(*)
优化不足,COUNT(1)
可能稍微快一点。
- 一些旧版本的数据库(尤其是 MySQL 较早版本)中,
- 缺点:
- 在现代数据库中,性能差异几乎可以忽略不计。
- 可读性不如
COUNT(*)
直观。
三. COUNT(*) 和 COUNT(1) 的区别对比
比较点 | COUNT(*) | COUNT(1) |
---|---|---|
统计逻辑 | 统计所有行的数量,包括 NULL | 统计生成的伪列(值为 1)的非 NULL 值数量 |
优化支持 | 现代数据库通常对 COUNT(*) 有专门优化 | 部分数据库中可能优化程度略低 |
性能差异 | 在现代数据库中,性能差异极小甚至没有 | 与 COUNT(*) 性能基本一致 |
语义清晰度 | 更符合标准 SQL 语义,容易理解 | 语义较不直观,可能引发误解 |
四. 不同场景下的使用
-
常规使用场景:
- 建议使用
COUNT(*)
,因为其语义明确,兼容性强,现代数据库对其优化通常很好。
- 建议使用
-
数据库特定优化:
- 如果使用的是某些旧版数据库,且性能测试显示
COUNT(1)
优于COUNT(*)
,可以考虑使用COUNT(1)
。
- 如果使用的是某些旧版数据库,且性能测试显示
-
查询计划和调优:
- 在复杂查询中,如果查询计划表明
COUNT(*)
性能存在瓶颈,可以尝试测试COUNT(1)
的性能差异。
- 在复杂查询中,如果查询计划表明
-
与其他统计函数结合:
- 如果需要统计某列中非 NULL 的行数,建议使用
COUNT(列名)
,而不是COUNT(*)
或COUNT(1)
。
- 如果需要统计某列中非 NULL 的行数,建议使用