前言
统计表中数据的条数是非常常用的操作,但是咱们常用的InnoDB存储引擎计数函数是现时统计的,所以会出现性能的问题,这次我准备分享计数函数count的原理,保证之后遇到计数方面的问题都可以轻易灵活的解决
与MyISAM存储引擎相比,MyISAM存储引擎是自己记录了表中数据的条数,但是如果加入筛选条件,也是需要实时统计的
目录
InnoDB存储引擎为什么不对表中数据条数备份
使用redis来记录MySQL表中的总条数
结论
原因分析
使用MySQL表来记录MySQL各表中的总条数
结论
原因分析
各种count计数函数的性能差距对比
count(参数)计数函数的原理
count()计数函数效率排行榜
InnoDB存储引擎为什么不对表中数据条数备份
1、加入筛选条件之后,这个记录的条数用不上
2、即使不加入筛选条件,MySQL是由MVCC并发版本控制的,在事务的交互中有时候会读取过期版本的数据的,此时记录的这个条数也不会准确
所以我们要是有count(*)统计数据,准确率高
使用redis来记录MySQL表中的总条数
结论
不太合适
原因分析
使用redis来存储总条数,redis不会永久的保存,所以会出现缓存丢失
当然Redis每次重新启动可以让MySQL执行一次count(*)查询,更新redis记录的总条数
但是无法解决MySQL增加数据,redis既要增加记录的总条数又要读取这个总条数,如果是先读去总条数,后增加维护的总条数会造成读取的数据与真实数据不一致
用缓存维护有丢失数据和计数不精确的问题
使用MySQL表来记录MySQL各表中的总条数
结论
是可行的
原因分析
我们使用MySQL表来维护,相比于存储到redis中的优势
1、MySQL本身就保证了数据不会有丢失风险
2、通过MySQL事务的操作可以做到表中总条数增加和读取总条数不会出现数据不一致的情况
各种count计数函数的性能差距对比
count(*)、count(主键id)、count(字段)和count(1)性能相差到哪里
count(参数)计数函数的原理
count()是⼀个聚合函数,对于返回的结果集,一行一行的判断,如果count函数的参数不是NULL,累计值就加1,否则不加。昀后返回累计值
所以效率的区别就出现在查询到每一行的参数值,并判断这个参数值是不是等于null的事情上了
count(字段)
一行一行找这个字段的值,并且判断这个值是不是为空,不为空了累加
count(1)
一行一行的遍历,但是不需要取值了,因为这个参数是一个常数,也不需要判断是否为空,因为不可能为空,参数就是一个常数
count(主键id)
一行一行找主键id的值,并且判断这个值是不是为空,不为空了累加,但是它是比count(字段)快的,因为找主键id是走主键索引的,在这个地方省下了时间,所以count(主键id)比较快
count(*)
count(*)函数不会一行一行的取出参数的值,⽽是专⻔做了优化,不取值。count(*)肯定不是 null,直接按⾏累加,运行过程和count(1)比较相似
count()计数函数效率排行榜
count(*) ≈ count(1) > count(主键id) > count(字段)