【Mysql实战45讲】14 count(*)

如果有个页面经常要显示交易系统的操作记录总数,如何计数?

  • 如果用redis来保存这个表的总行数,可能存在一些问题,比如在数据表中插入一行数据后,准备将redis中的计数+1时,redis异常重启了,那刚刚这个+1的操作就丢失了,这个场景下是有解的,就是redis异常重启后,到数据库里单独执行一次 count(*) 来获取真实的行数,并写回到redis即可,由于异常重启不是经常出现的状况,所以这一次全表扫描的成本是可以接受的。但还有个问题是,redis所计数的值是不精确的,比如在执行新增记录逻辑时,先写数据库,再改redis计数,读的时候先读redis,再读数据表中的记录,此时可能出现:插入一行数据后,还没来得及给redis中的计数+1,就读了redis中的计数和数据表中的记录。
  • 所以可以将这个计数放到数据库中用单独的一张计数表进行记录。InnoDB支持崩溃后数据的恢复,不会让数据丢失,并且由于InnoDB支持事务,所以可以避免redis中的不精确问题:比如先插入数据,再更新计数,如果在这中间进行了读的操作,由于前面的更新事务还没提交,更新的操作对读操作是不可见的,所以读到的数据还是未插入前的数据。

count(1) 和 count(*)

  • count(1) 会遍历整张表,但不取值,按行进行累加
  • count(*) 也不取值, InnoDB 专门对其进行了优化
  • 查找效率方面,两者差不多,尽量使用 count(*)

重点:先插入数据,再更新计数表中的值。因为更新计数表时会涉及行锁的竞争,所以先插入再更新能最大程度的减少事务之间的锁等待,提升系统的并发度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值