MySQL简单技巧(一):count(*)、count(1)、count(id)等效率功能比较

前文

  最早在用MySQL count的时候,一直不懂count(*)、count(1)、count(id)这些用法的差别,所以每次就用count(*),当有统计字段需求的时候就用count(字段),所幸也大多无碍,不过了解和掌握这些区别也是非常重要的!

效率

  先说结论,单从效率上讲:

效率:count(字段)<count(主键 id)<count(1)≈count(*)
  所以平常用的时候推介用count(*),那这个原理是啥?
  首先我们得明白MySQL服务端是server+执行引擎(比如innodb、myisam)的架构,所以针对不同的引擎来讲,count的原理是不同的。比如myisam,在没有where条件下,是可以直接统计文件数目返回,所以速度非常快,但由于不支持事务,所以该引擎用的很少,在这里就不多做讨论。

  主要是innodb,作为MySQL的默认引擎以及当前最常用的执行引擎来讲,它就没有所谓的专门统计,所以count原理就是:执行引擎取出一条条数据返回给server端统计,直到全部取完后返回给客户端结果。那为啥innodb不搞一个专门计数的类似于文件的来统计呢?这样在每次插入删除的时候,对应的更新不是很简单吗?因为MVCC的缘故,为了维持不同事务下的行数不同,所以count对应返回的结果是不同的!!

不同count的原理说明

  明白了上面的基础后,来看下不同的count下,innodb是如何处理的?count统计的时候我们要区分是否为null,这就有两种统计方式:不管是否为null,只要存在这行记录就+1;如果为null,该记录就不纳进统计,因此是否判断为null会影响到计数的准确性和速度(相当于每一行都不判断,当百万行、千万行时效率提升明显),所以总结如下:

  • count(*):不做判断,取一行,server就+1(MySQL做了优化)
  • count(1):不做判断,去一行,server就+1(因为是true,所以只要有就+1)
  • count(id):取出对应的id,判断不是null,server+1,因为id会走索引最小的遍历(而字段不一定有索引,则只能走聚蔟索引),所以效率稍高,但是MySQL没有针对主键一定不为空做优化
  • count(字段):取出对应的字段,判断不是null,server+1(要增加判断,所以效率最低)

如何优化

  明白了上述原理后,我们可以考虑下如何优化?比如一张表1000w行数据,如果在业务很频繁的从数据库取出所有行数,那每次都要一行行的取效率是何其慢,这里推介简单优化方法:
MySQL新增一个表来记录总数:因为新增一个表来计数,这样每次都能查到最新的数值,而且在同一个事务里的话还保持了mvcc的特点,即每个事务查到的结果可以不一致;并且redo log的存在保证了MySQL异常重启时也能保证数据的不丢失

总结

  技巧篇会总结些简单的功能,记录到此~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值