美文网首页
Mysql | 对count(*)的一些思考(一)

Mysql | 对count(*)的一些思考(一)

作者: leafzl | 来源:发表于2019-01-06 07:18 被阅读85次

    极客时间《Mysql实战45讲》的笔记:

    我们在开发的时候,经常用count()统计总条数,然后根据这个总条数,返回给前端进行分页,那么count()的底层是怎么实现的。

    count(*)的实现方法

    在不同的引擎中,count(*)的实现机制不同

    1.MyISAM 引擎把一个表的总行数存在了磁盘上,,因此执行 count(*) 的时候会直接返回这个数,效率很高(加上where条件就应当别论了)

    2.而 InnoDB 引擎就麻烦了,它执行 count(*) 的的时候,需要把数据一行一行的从引擎里读出来,然后累积计数。

    那为什么InnoDB不跟MyISAM一样,把数字存起来呢?

    因为InnoDB的多版本并发控制(MVCC)的原因。即便同一时刻多个查询,InnoDB也不确定那返回多少行。

    image

    根本的原因是因为InnoDB支持事务,可重复读默认是隔离级别,是通过多版本并发控制,也就是 MVCC来实现的。查询的count(*),要根据每个会话的情况而决定的。

    对频繁操作count(*),有什么方法

    1.用缓存系统保存计数

    这种方法是十分容易想到的,但他有2点致命的缺陷。

    1.数据易丢失

    redis的数据是不能永久的留在内存里的,虽然redis有持久化的机制,即便是这样,仍然可能丢失,假设:你的在数据库插入一条数据,redis这时候加1,突然redis异常重启,然后你把持久化的数据读进去,刚刚加1的数据就丢了。

    2.逻辑上不精确

    有这样一个页面,它要求显示总条数,还要显示最近的100条。

    image

    进行上面的操作,有问题吧。

    2.在数据库保存计数

    保存在数据库中,首先解决了数据丢失的问题,

    因为InnoDB支持事务的缘故,也解决了计数上不精确的问题。

    image

    今天就记录到这里啊。

    image

    相关文章

      网友评论

          本文标题:Mysql | 对count(*)的一些思考(一)

          本文链接:https://www.haomeiwen.com/subject/mtvjrqtx.html