1. COUNT()
是什么?
在 MySQL 中,COUNT()
是一个聚合函数,用于统计结果集中行的数量。它常见的几种用法包括:
COUNT(*)
:统计结果集中所有行的数量,包括包含NULL
的行。COUNT(1)
:统计结果集中所有行的数量,和COUNT(*)
功能相同。COUNT(字段名)
:统计结果集中某个字段非NULL
值的数量。COUNT(主键字段名)
:统计结果集中某个主键字段非NULL
值的数量。
简单例子:
假设有一个 users
表,数据如下:
id
name
age
1
Alice
25
2
Bob
NULL
3
Charlie
30
NULL
NULL
20
-
COUNT(*)
:SELECT COUNT(*) FROM users;
结果:
4
(统计所有行,无论字段是否为NULL
)。 -
COUNT(id)
:SELECT COUNT(id) FROM users;
结果:
3
(统计id
列非NULL
值的数量)。 -
COUNT(DISTINCT age)
:SELECT COUNT(DISTINCT age) FROM users;
结果:
3
(去重后的age
值:25, 30, 20
)。
先给结论:
执行效率排序(InnoDB)
方法
功能
执行过程
性能情况
COUNT(*)
统计所有行的数量(包括 NULL
行)
遍历表或索引,计算所有行数,InnoDB 遍历聚簇索引
最高效率,InnoDB 会通过聚簇索引快速扫描
COUNT(1)
统计所有行的数量
优化器会将其转换为 COUNT(*)
,功能和过程完全相同
与 COUNT(*)
相同,性能无差异
COUNT(主键字段)
统计所有行的数量(主键字段非 NULL
)
通过主键索引扫描,所有主键字段值非 NULL
高效,MySQL 会直接使用主键索引进行扫描
COUNT(字段)
统计指定字段非 NULL
的行数
如果字段有索引,使用索引扫描;没有索引则需要全表扫描
如果字段有索引,效率较高;无索引时性能较差
具体原因解释:
-
COUNT(*)
:COUNT(*)
的效率在 InnoDB 中通常最高,因为它会遍历整个表或索引计算所有行数。对于 InnoDB,它通常依赖于聚簇索引来获取表的行数,聚簇索引直接将表数据存储在索引叶节点中,避免了额外的查找开销,因此相对高效。
-
COUNT(1)
:COUNT(1)
实际上和COUNT(*)
完全等效。因为1
是一个常量,不涉及任何字段,MySQL 会优化COUNT(1)
为COUNT(*)
,两者的执行过程是一样的。所以,性能与COUNT(*)
相同。
-
COUNT(主键字段)
:- 由于 InnoDB 使用聚簇索引,主键索引包含了表的所有行数据。如果你使用主键字段来计数,MySQL 会利用主键索引来扫描行。相比全表扫描,主键索引扫描通常更高效。因此,
COUNT(主键字段)
在 InnoDB 中通常比COUNT(字段)
更高效。
- 由于 InnoDB 使用聚簇索引,主键索引包含了表的所有行数据。如果你使用主键字段来计数,MySQL 会利用主键索引来扫描行。相比全表扫描,主键索引扫描通常更高效。因此,
-
COUNT(字段)
:- 有索引的字段:如果字段有索引,MySQL 会直接扫描索引来计算非
NULL
的行数,效率较高。 - 没有索引的字段:如果字段没有
- 有索引的字段:如果字段有索引,MySQL 会直接扫描索引来计算非