ps:以下仅适用于 InnoDB 存储引擎
count()是什么
count(参数)是聚合函数,用来统计记录中对应参数字段不为 NULL 的记录条数。
count(字段)执行过程
- 字段是主键时,在存储引擎中遍历索引(优先选择二级索引中最短的,没有二级索引就用聚簇索引),每次读取一条记录,交给server层,server层再读取记录中对应的字段,判断是否为 NULL,为 NULL 则变量 count 加1。
为什么要优先二级索引:因为二级索引只存储了主键值和二级索引字段,所以相同记录数,二级索引会比聚簇索引更节省空间,意味着 B+ 树更矮胖,对磁盘的 I/O 次数更少。
-
字段是二级索引时,在存储引擎中遍历该字段的二级索引,后续流程同主键。
-
字段是普通字段时,对全表扫描,对每条记录判断该字段是否为 NULL。
验证一:字段是主键,当表中索引只有主键索引时,使用聚簇索引。
验证二:字段是主键,当表中索引有二级索引时,使用二级索引。
验证三:字段是二级索引,使用该字段的二级索引。
验证四:普通字段,全表扫描。
count(1)
count(1) 里面是1,对于每条记录条件1 != NULL
成立,不需要再读取记录中某个字段进行判断是否为 NULL,循环遍历索引(优先选择二级索引中最短的,没有二级索引就用聚簇索引),将读取的记录返回给server层,直接 count 变量加 1。因为不要查询具体字段的值,它的效率比 count(字段) 的效率高。
count(*)
使用 count(*) 时 MySQL 会把它当作 count(0) 处理。0 != NULL
,所以它的执行过程和 count(1) 是等价的。