InnoDB引擎不同 count()对比

count() 函数相关知识

不同的 count 用法对比

count() 的语义:count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是 NULL,累计值就加 1,否则不加。

所以,count(*)、count(主键 id) 和 count(1) 都表示返回满足条件的结果集的总行数;而 count(字段)表示返回条件的数据行里,参数字段不为 NULL 的总个数。

提炼:count(字段) 统计的是 字段不为 NULL 的结果总数;其余情况下统计的是全部结果(无论字段是否为 NULL)。

至于分析性能差别的时候,你可以记住这么几个原则:

  1. server 层要什么就给什么;
  2. InnoDB 只给必要的值;
  3. 现在的优化器只优化了 count(*) 的语义为 “取行数”,其他“显而易见”的优化并没有做。

下面逐个解释:

对于 count(主键)来说,InnoDB 引擎会遍历整张表,把每一行的 id 值都取出来,返回给 server 层。server 层拿到 id 之后,判断是不可能为空的,就按行累加。

对于 count(1) 来说, InnoDB 引擎遍历整张表,**但不取值。**server 层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加。

对于 count(字段) 来说:

  1. 如果这个“字段”是定义为 not null 的话,一行行的从记录里面读出这个字段,判断不能为 null,按行累加。
  2. 如果这个“字段”定义允许为 null,那么执行的时候,判断有可能是 null,还要把取值出来再判断一下,不是 null 才累加。

但 count(*) 是个例外,**并不会把全部字段取出来,而是专门做了优化,不取值。count(*)肯定不是 null,按行累加。

结论:按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(*),所以我建议你,尽量使用 count(*)。

🌰:
在这里插入图片描述
我创建一张 user 表,表里面的属性有 id(主键)、username、password、birthday。图中可以看到其中 id=13 这一条记录的 username = NULL。
执行 SQL 语句:

-- 不同 count() 查询数量对比
select count(*), count(id), count(1), count(username) from user;

查看结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值