MySQL 中COUNT(*),COUNT(1),COUNT(普通字段),COUNT(索引字段)的效率和区别?

目录

1. 结论

2. 在MyISAM 存储引擎中

3. InnoDB 存储引擎中


1. 结论

结论一:COUNT(*)和COUNT(1)都是对所有结果进行COUNT,二者区别不大,效率没有明显差别;

结论二:COUNT(普通字段)得到的结果可能与COUNT(1),COUNT(*),COUNT(主键字段)不一样,因为普通字段可能为NULL,为NULL则不会被统计进去,后面三者则是按行统计,只要一行中有一个字段不为NULL就会被统计进去;

结论三:执行效率 COUNT(*) = COUNT(1) > COUNT(主键字段) > COUNT(普通字段);

2. 在MyISAM 存储引擎中

在MyISAM存储引擎,因为每张表中都有一个 mate 信息记录 row_count 的值,不需要进行重新计算,所以时间复杂度为O(1);

而且,MyISAM 存储引擎中只有表级锁,能够确保数据的准确性和唯一性

3. InnoDB 存储引擎中

(1)在InnoDB存储引擎中,表中没有具体的值来记录行数,需要进行全表扫描,都是需要用的时候再去进行COUNT计算,所以时间复杂度为O(n)。原因就是因为InnoDB存储引擎的行锁支持高并发和MVCC的版本控制,会导致统计数据不准确,不像MyISAM那样是表级锁,一次只能有一个线程操作。

(2)在有非聚簇索引的情况下,COUNT(1),COUNT(*),COUNT(主键字段)都是优先通过非聚簇索引统计数据,因为非聚簇索引的B+树不存储完整数据,只有索引列和主键值,数据量小,IO成本低,是优化器会优先选择的做法,并且如果有多个非聚簇索引,优化器会选择索引列最小(key_len最小)成本最低的一个来进行统计。COUNT(普通字段)就需要通过聚簇索引的B+树来进行统计,因为非聚簇索引的B+树中没有普通字段,无法通过非聚簇索引统计记录数。

(3)在没有非聚簇索引的情况下,COUNT(1),COUNT(*),COUNT(普通字段),COUNT(索引字段)都是通过聚簇索引来进行统计,如果字段为NULL也是统计不进去的,所以COUNT(普通字段)统计的结果一定小于等于 COUNT(1),COUNT(*),COUNT(索引字段) 的结果。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值