面试拷打之MySQL如何统计表中记录的数量

上午刚面一个Java开发岗,深刻体会到自己基础的不扎实,写下此篇,谨记在心。

面试官:你平时如何统计一张表的记录数量

菜鸡小川:count(1)

面试官:那你认为count(1),count(索引字段),count(*)之间谁的效率高

菜鸡小川:count(1)==count(索引字段)>count(*)--非常干脆的回答了

回答完,楞了一下,死去的记忆似乎想唤醒我,but,没给我唤醒

不知有多少同学和我一样,认为count(*)肯定是最慢的。以为和select * 一样肯定是要扫所有数据怎么都得慢点。

只能说八股不是靠背的,还得深刻理解啊。(但我每次看完理解了又忘了。。。注定天资平平,理解的不够深刻)

不过,好记心不如烂笔头,那就写下来分析一下吧。

首先分析count()

count()是一个聚合函数,作用就是统计记录数据的数量。准确的说是统计参数不为null的行记录数量。

举个例子,count(id)就是统计id不为空有多少行数据。

特殊:count(1)就相当于全表统计了,因为1永远不为null嘛。

count()是如何做到统计数量的呢

这就的说到mysql的存储引擎和服务层了。mysql的存储引擎是用于存储具体的记录的,服务层是用于做一些基础的计算。

那我们先分析一下count(主键索引),底层是如何做到的:

首先假设没有二级索引了,当发起这个命令时会去找这个主键索引的b+树并找到第一个节点依次向后扫描,每每扫到数据就返回server层做判断,判断这个字段是否为空,如果不为空则数量加1,直至扫到最后一个节点的最后一条记录,然后再将计算好的数量返回给客户端。

所以,当你直接使用count(1)的时候,就省去了判断null的只一个步骤,所以自然是更快的。

那count(*)呢,其实呀,一样的,count(*)相当于count(0),所以也是不需要判断的。这可不是我乱说的,mysql官方专门提出了:

那有人会好奇,前面说的是假设没有二级索引,那如果有呢。

如果有二级索引,就会直接走二级索引,这个也比较好理解,因为,二级索引这棵树的叶子节点只需要存主键,所以自然能存的内容更多,那树也会比较窄,io的效率肯定是要高一些的。

总结一下:count(1)==count(*)>count(索引字段)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值