MYSQL--count(*),count(Id),count(1)的区别和性能对比

11 篇文章 0 订阅
10 篇文章 0 订阅

下面是官方文档的描述,我理解可能有问题,但是官方文档肯定靠谱的

COUNT(*) is somewhat different in that it returns a count of the number of rows retrieved, whether or not they contain NULL values.

For transactional storage engines such as InnoDB, storing an exact row count is problematic. Multiple transactions may be occurring at the same time, each of which may affect the count.

InnoDB does not keep an internal count of rows in a table because concurrent transactions might “see” different numbers of rows at the same time. Consequently, SELECT COUNT(*) statements only count rows visible to the current transaction.

To process a SELECT COUNT(*) statement, InnoDB scans an index of the table, which takes some time if the index is not entirely in the buffer pool. For a faster count, create a counter table and let your application update it according to the inserts and deletes it does. However, this method may not scale well in situations where thousands of concurrent transactions are initiating updates to the same counter table. If an approximate row count is sufficient, use SHOW TABLE STATUS.

InnoDB handles SELECT COUNT(*) and SELECT COUNT(1) operations in the same way. There is no performance difference.

注意本文的讨论背景是InnoDB引擎。

count 本身是一个聚合函数,本质过程无非是对选择的结果集进行一行行的判断,如果count参数不是NULL,累计值就加1,否则(count的参数 is NULL)就不加了,最后返回总累计值。

先说结果

按照效率排序的话 count(*)=count(1)>count(主键Id)>count(字段)

所以当然是尽量使用 count(*) 啦!

分析原因之前,先简单分析一下 MySQL 的 server层和引擎层的两个原则:

server 要什么引擎层就会提供什么;

引擎层只会提供必要的值

另外,要注意的是优化器对 count(*) 进行了专门优化

下面分析一下原因:

count(id)

引擎层会遍历整张表,把每一行的id都取出来,返回给server层,server 层会根据id判断,不为NULL的就会累计值加一。

count(1)

InnoDB引擎也会遍历整张表,但是不用取值。server层会对每一个返回的1进行判断,如果不为NULL,累计值加一。

count(字段)

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

count(*)

这里InnoDB会先扫描一个(最优的)索引,如果索引不全部在 buffer pool 会需要点时间加载。

官方文档说对于更快的统计,可以创建一个技术的表,只要涉及add 和 delete 可以进行更新。当然在高并发场景这样可能不太好用。

近似统计 SHOW TABLE STATUS 

如果不准确的统计可以接受,可以使用 SHOW TABLE STATUS 进行近似的统计。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值