整理测试count(1)、count(*)以及count(列)的区别

背景:
业务需要对多个数据库表进行count统计,很早以前就听一个同事说count(1)比count()要快,说count()要全表扫描而count(1)则不用…后来我百度过好像说这种说法是错误的,所以我一直还是用count(*),今天在此详细总结并测试下这几者的区别(网上百度的太乱了)!


一、测试

mysql版本:5.7.20
这里写图片描述

测试表:InnoDB 引擎

CREATE TABLE `t_mobilesms_11` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `userId` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
  `mobile` varchar(24) NOT NULL DEFAULT '',
  `billMonth` varchar(32) DEFAULT NULL,
  `time` varchar(32) DEFAULT NULL,
  `peerNumber` varchar(64) NOT NULL,
  `location` varchar(64) DEFAULT NULL,
  `sendType` varchar(16) DEFAULT NULL,
  `msgType` varchar(8) DEFAULT NULL,
  `serviceName` varchar(256) DEFAULT NULL,
  `fee` int(11) DEFAULT NULL,
  `createTime` datetime DEFAULT NULL,
  `lastModifyTime` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `Mobile` (`mobile`),
  KEY `idx_userId` (`userId`)
) ENGINE=InnoDB AUTO_INCREMENT=71185 DEFAULT CHARSET=utf8

网上有种说法count(1)比count(*)快!我看了下他们的测试,发现有很大问题
这里写图片描述
可以看到上面第一次测试时时间耗费较多,而下面再测试时耗时很少,这是由于数据库缓存的原因!但居然有人把这作为结论表示count(*)效率不行也是奇葩~
这里写图片描述
这里写图片描述
此处测试多次,发现两者耗时几乎相同!

下面继续看执行计划:
这里写图片描述
这里写图片描述
发现执行计划一模一样,所以我们确定count(*)和count(1)的效率是一样的!

注意:count(1)并不是值count(第一个字段)!

mysql底层对count(*)有优化,会选择最有效率的方式去执行count操作,两者没有性能差异,效率都比较高。


测试count(列):

注意索引列!
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

在比较 count(*)/count(1) 和 count(列) 的效率时,要注意两者本质的区别不是效率!

count(*) /count(1)将返回表格中所有存在的行的总数包括值为 null 的行,然而 count(列名) 将返回表格中除去 null 以外的所有行的总数 (有默认值的列也会被计入),这点对于所有数据的 COUNT 计算都是一样的!

所以先要明确这一点!再看效率测试,我们可以发现除了count(id)主键 比较快之外,其他列的无论是否建索引,速度都慢于count(*),有人得出这个结论:列的偏移量决定性能,列越靠后,访问的开销越大这个我目前的测试还不能确定


二、结论

InnoDB引擎下:

1.count(*)和count(1)的效率是一样的!两者没有性能差异!
如果表存在主键,他们都是根据主键去count的,速度都较快;如果不存在主键,则速度都较慢!

2.count(1) /count(*)会统计表中的所有的记录数,包含字段为null 的记录;
count(列名) 会统计该字段在表中出现的次数,不统计字段为null 的记录。
且在效率方面count(非主键列)的效率往往低于count(*)/count(1) !count(主键列)效率差不多!

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值