聊一聊关于MySQL的count(*)

坚持更新Java技术栈相关总结,Java、MySQL、各类中间件等,关注公众号【阿丸笔记】获取第一时间更新。
收集技术相关电子书、面试题,有须要的小伙伴能够关注公众号【阿丸笔记】,无套路领取。

1. 背景

自从你们对于MySQL数据库的稳定性有了更高的追求后,常常有小伙伴有这样的疑问,对于count(*)这样的操做,有没有正确的姿式,或者有没有能够优化的地方?mysql

但答案比较残酷,若是已经使用了正确的索引,那么基本上没有能够优化的地方。一旦出现慢查询了,它就是慢查询了,要改,只能本身计数或者经过其余搜索平台来作。面试

今天,就一块儿来看看为何会这样,并对你们平常会遇到的一些的困惑进行解答。sql

2. count(*)的实现方式

听说,MyISAM 引擎把一个表的总行数存在了磁盘上,所以执行 count(*) 的时候会直接返回这个数,效率很高。
而咱们的mysql通常都是用Innodb的引擎,Innodb是怎么实现count操做的呢?
InnoDB 引擎就比较麻烦了,它执行 count(*) 的时候,须要把数据一行一行地从引擎里面读出来,而后累积计数。
因此,当咱们的表里面的记录愈来愈多的时候,count(*)就会愈来愈慢。

固然,咱们这里说的都是不带where条件的,若是带上where条件的话,MyISAM也是很慢的。数据库

3.正确的打开方式

嗯,首先仍是说,mysql上不太推荐用count(*)来作统计相关业务,尤为是表很是大的状况下。
那若是业务比较小,须要快速上马,那么,至少应该保证count(*)带上了科学的where条件,而后,这个表也已经创建了科学的索引。
1)若是count(*)带上的where条件,并且可以走覆盖索引,那仍是能够偶尔走一走的。
2)若是count(*)带上的where条件,可以走索引,可是须要回表,那么这种就会比较危险,尤为是随着表规模的扩大,终究是一颗雷。
3)若是纯粹count(*),或者where条件没有任何索引,万万万不推荐!
那对于统计类的业务,推荐的几种作法:
1)带自增id的,能够用最大id来近似获取
2)本身计数

3)其余数据分析平台进行聚合函数

4. 可否用表统计信息代替count(*)

有同窗在平常使用过程当中,问可否使用 系统表的统计信息 来代替count。

答案是不行。这里的tableRows只是一个参考值。性能

这里的表统计信息,其实是使用show table status获取的。这个值是如何获得的呢?咱们须要了解下mysql的采样统计方法。
为何要采样统计呢?由于把整张表取出来一行行统计,虽然能够获得精确的结果,可是代价过高了,因此只能选择“采样统计”(因此其实mysql本身也没有count(*)的好方法)。
采样统计的时候,InnoDB 默认会选择 N 个数据页,统计这些页面上的不一样值,获得一个平均值,而后乘以这个索引的页面数,就获得了这个索引的基数。
而数据表是会持续更新的,索引统计信息也不会固定不变。因此,当变动的数据行数超过 1/M 的时候,会自动触发从新作一次索引统计。

所以,这个采样估算得来的值,是很不许的。有多不许呢,官方文档说偏差可能达到 40% 到 50%。优化

4.关于那些奇奇怪怪的count(?)

在看一些老代码查询的时候,咱们常常会看到count(1),count(id),count(字段)等方式,那它们纠结孰优孰劣,到底有没有性能上的差别呢?spa

这里,咱们先要弄清楚 count() 的语义。
count() 是一个聚合函数,对于返回的结果集,一行行地判断,若是 count 函数的参数不是 NULL,累计值就加 1,不然不加。最后返回累计值。
1)count(主键id)
InnoDB 引擎会遍历整张表,把每一行的 id 值都取出来,返回给 server 层。server 层拿到 id 后,判断是不可能为空的,就按行累加。
2)count(1)
InnoDB 引擎遍历整张表,但不取值。server 层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加。
3) count(字段)
若是这个“字段”是定义为 not null 的话,一行行地从记录里面读出这个字段,判断不能为 null,按行累加;
若是这个“字段”定义容许为 null,那么执行的时候,判断到有多是 null,还要把值取出来再判断一下,不是 null 才累加。
4)count(*)
并不会把所有字段取出来,而是专门作了优化,不取值。count(*) 确定不是 null,按行累加。
因此结论是:按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(*),因此我建议,尽可能使用 count(*)。


扫码关注个人公众号“阿丸笔记”,第一时间获取最新更新。
无套路获取Java技术栈电子书、各个大厂面试题

相关文章
相关标签/搜索