Featured image of post MySQL - Count

MySQL - Count

count(主键)

在通过 count 统计有多少记录时,在 server 层会维护一个叫 count 的变量。server 层会循环向 InnoDB 读取一条记录,如果 count 函数指定的参数不为 NULL,那么就会对变量 count + 1,直到符合查询条件的全部记录被读完

以下语句为例:

1
select count(id) from t_order;

当表中不存在二级索引时,InnoDB 会循环遍历聚簇索引,将读取到的记录返回给 server 层,然后读取记录中的 id 值来判断是否将变量 count +1

当存在二级索引时,由于相同数量的二级索引比聚簇索引占用的存储空间更小,因此优化器会选择二级索引进行遍历

count(1)

以下语句为例:

1
select count(1) from t_order;

当不存在二级索引时,InnoDB 会便利聚簇索引,将读取到的记录返回给 server 层,但不会读取记录中任何字段的值。因为 count 函数的参数是 1,很明显 1 != NULL, 因此每读到一条数据,都会将变量 count +1

当存在二级索引时,遍历对象同样会变为二级索引

count(*)

对于 select * 来说,* 等同于所有字段值

但对于 count() 来说,实际等同于 count(0)。因此 count() 与 count(1) 的执行过程基本是一样的,没有什么差别

并且 MySQL 对于 count(*) 和 count(1) 有一个优化,如果存在多个二级索引的时候,优化器会选择 key_len 最小的二级索引进行扫描

count(字段)

count(字段) 相比以上几种的执行效率最差

为什么要通过遍历的方式来计数

在 InnoDB 中是支持事务的,因此在同一时刻的多个查询,由于多版本并发控制(MVCC)的原因,InnoDB 应该返回多少行也是不确定的

Licensed under CC BY-NC-SA 4.0
最后更新于 Oct 12, 2020 00:00 UTC