count(*)和count(1)谁更快?,mysql中的count的秘密

count(*)和count(1)谁更快?,mysql中的count的秘密

count(主键)的执行过程

在我们执行count语句的时候我们mysql的server层会维护一个count的变量。server层会像innodb读取一条记录,如果count指定的参数列表不为null(当前的值时是不是为null),那么我们的count变量就会+1,如何要求的所有记录都读完毕就退出循环,最后的count变量的值会发送给客户端。

InnoDB通过B+ tree记录数据,索引的类型分为聚簇索引和二级索引他们的区别就是一个存放真实数据,二级索引存放的是当前记录的主键,

我们我们的表只有主键没有其他索引那么我们当前命令查找的索引是通过主键,如果有普通索引和主键当前的命令走的是普通索引,普通索引的效率会比我们的主键快,因为聚簇索引包含真实数据,普通索引包含当前记录的主键,这样我们的I\O成本就会小。

count(1)的执行原理

在inndob遍历主键索引的时候没有二级索引的情况,其实count(1)和count(主键)的差距就是count主键需要获取当前这个列的值是否为null,而count(1)不需要获取记录中的值,他只需要获取当前记录是否为null即可。

如果有二级索引和主键那么走的就会是普通索引,原理是一样的为了减少I\O。

count(*)的执行原理

其实count(*)和count(1)的执行过程是基本一致的。性能什么差异。在mysql的官方文档有一句话,innoDB会让count( *)和count(1)一样的处理方法,在mysql的业务层中,会把0代替为

select count(0) as 'count(*)' from .....

当然如果我们有多个普通索引,那么就会选择一个key_len最小的。

INNODB为什么使用遍历计算个数

因为InnoDB是支持事物的,同时支持多个查询,由于多版本并发控制(MVCC)的云隐,INNODB应该返回多少行也是不确认的。无法像MyISAM一样只维护一个row_count变量。

MyISAM

MyISAM执行一个count语句时间复杂度是O(1)因为在我们MYISAM引擎下维护一个row_count变量用来记录个数,因为表锁保证一致性,所以执行row_count就是count函数的执行结果。

如何优化count在innodb

如果我们业务精确性不是很高可以像Google搜索一样取近值。

如果精确性很大,可以建立外表来记录数量。

你可能感兴趣的:(mysql,数据库)