外观
MySQL 中 count 的区别
语法含义
count(*)
:表示统计结果集中所有记录的数量,无论记录中的字段是否为NULL
,都会被统计在内。它是对表中所有行进行计数,不考虑具体的列。count(1)
:这里的1
可以看作是一个常量值,count(1)
的作用也是统计结果集中的记录数量。它同样会对每一行进行计数,不管行中的数据是什么,只要有行存在就会计数。count(字段名)
:只统计指定字段不为NULL
的记录数量。也就是说,如果某一行的指定字段值为NULL
,那么这一行不会被计入统计结果。
性能表现
count(*)
:在大多数情况下,count(*)
的性能是比较好的。因为MySQL
优化器会对count(*)
进行特殊处理,它会直接读取存储引擎中的行计数信息(如果存储引擎支持的话),而不需要实际去遍历每一行数据。例如,在InnoDB
存储引擎中,当使用count(*)
时,会通过索引快速统计行数。count(1)
:从性能上来说,count(1)
和count(*)
基本没有区别。MySQL
优化器在处理count(1)
时,会将其优化为和count(*)
类似的执行方式,同样会尝试利用存储引擎的行计数信息,而不是真正去检查每行中的常量1
。count(字段名)
:性能可能会受到影响,尤其是当指定的字段没有索引时。因为MySQL
需要逐行扫描数据,检查指定字段是否为NULL
,这会增加I/O
开销和CPU
计算量。如果指定的字段有索引,MySQL
可以利用索引来快速过滤掉NULL
值,从而提高统计效率。
NULL
值处理
count(*)
和count(1)
:不考虑字段的NULL
值情况,只要有行存在就会进行计数。例如,有一个表test
如下:
CREATE TABLE test (
id INT,
name VARCHAR(20)
);
INSERT INTO test VALUES (1, 'Alice'), (2, NULL), (3, 'Bob');
执行 SELECT count(*)
和 SELECT count(1)
都会返回 3
,因为它们统计的是表中的所有行。
count(字段名)
:会忽略指定字段为NULL
的行。对于上述test
表,执行SELECT count(name)
会返回2
,因为name
字段为NULL
的行不会被计入统计结果。
总结
- 如果需要统计结果集中的所有记录数量,不考虑字段的
NULL
值情况,建议使用count(*)
,因为它是最简洁且性能通常较好的方式。 count(1)
在功能和性能上与count(*)
基本一致,可以根据个人编程习惯选择使用。- 当只需要统计指定字段不为
NULL
的记录数量时,使用count(字段名)
。但要注意,如果指定字段没有索引,可能会影响性能。