count() 是一个聚合函数,函数的参数不仅可以是字段名,也可以是其他任意表达式,该函数作用是统计符合查询条件的记录中,函数指定的参数不为 NULL 的记录有多少个
count() 函数的参数是字段名,如下
select count(name) from t_order;
count() 函数的参数是数字 1 这个表达式, 如下:
select count(1) from t_order;
t_order 表中,1 这个表达式不为 NULL 的记录」有多少个,1 这个表达式就是单纯数字,它永远都不是 NULL,所以上面这条语句,其实是在统计 t_order 表中有多少个记录
count(主键字段) 执行过程
在通过 count 函数统计有多少个记录时,MySQL 的 server 层会维护一个名叫 count 的变量
server 层会循环向 InnoDB 读取一条记录,如果 count 函数指定的参数不为 NULL,那么就会将变量 count 加 1,直到符合查询的全部记录被读完,就退出循环。最后将 count 变量的值发送给客户端
count(1) 执行过程
InnoDB 循环遍历聚簇索引(主键索引),将读取到的记录返回给 server 层,但是不会读取记录中的任何字段的值,因为 count 函数的参数是 1
count(1) 相比 count(主键字段) 少一个步骤,就是不需要读取记录中的字段值,所以通常会说 count(1) 执行效率会比 count(主键字段) 高一点
count(*) 执行过程
count(*) 其实等于 count(0) ,也就是说,当你使用 count(*) 时,MySQL 会将 * 参数转化为参数 0 来处理
MySQL 会对 count(*) 和 count(1) 有个优化,如果有多个二级索引的时候,优化器会使用key_len 最小的二级索引进行扫描
只有当没有二级索引的时候,才会采用主键索引来进行统计
count(字段) 执行过程
采用全表扫描的方式来计数
如何优化 count(*)
对一张大表经常用 count(*) 来做统计,其实是很不好的, 耗时长
- 用近似值,explain 或者 show table status
- 用额外的表记录大小