https://www.jianshu.com/p/1b0a1f641e80]数据库
不一样引擎count(*)实现方式不一样
- MyISAM引擎把一个表的总行数记录在了磁盘上,执行count(*)会直接返回这个数值,效率很高。
- InnoDB,执行count(*),须要把数据一行行的从引擎中读出来,而后累积计数。
InnoDB对count(*)的优化
- 咱们知道,InnoDB是索引组织表,主键索引的叶子节点保存的是数据;普通索引的叶子节点保存的是主键值。因此,普通索引比主键索引小,对于count(*)这样的操做,遍历哪一个索引树获得的结果逻辑上是同样的,所以,MySQL优化器会找到最小的索引树来遍历,在保证逻辑正确的前提下,尽可能减小扫描的数据量,是数据库系统设计的通用法则之一。
show table status与count(*)
- show table status命令输出结果中有一个TABLE_ROW值,但不能代替cout(*),由于它是经过采样统计计算的,偏差较大(可能达到40%-50%)。
聚合函数count()
- count()是一个聚合函数,对于返回结果,一行行的判断,若是count函数的参数不是NULL,累计值就+1,不然不加,最后返回累计值。
- count(*)、count(id)、count(1)都表示返回知足查询条件的结果集的总行数;count(字段),表示返回知足条件的数据行里面参数字段不为NULL的结果的总个数。
不一样count参数性能对比
- count(主键id):InnoDB引擎会遍历整张表,把每一行id值都取出来,返给server层。server层拿到id后,判断是不可能为空的,就按行累加,再也不对每一个值进行NULL判断。
- count(1):InnoDB引擎会遍历整张表,但不取值。server层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加,再也不对每一个值进行NULL判断。
count(1)比count(主键id)执行的要快,由于从引擎放回id会涉及解析数据行,以及拷贝字段值的操做。
- count(字段):
一、若是参数字段定义NOT NULL,判断是不可能为空的,按行累加,再也不对每一个值进行NULL判断。
二、若是参数字段定义容许为NULL,那么执行的时候,判断多是NULL,还要把值取出来再判断一下,不是NULL才累加。
这也是定义字段时建议设置NOT NULL的缘由之一。
- count(*):前面说过,InnoDB专门对它作了优化
- 结论:对于InnoDB引擎,按效率排序,count(字段) < count(主键id) < count(1) ≈ count(*),建议尽可能使用count(*)