一文搞清楚MySQL count(*)、count(1)、count(col)区别


Posted in MySQL onMarch 03, 2022

在工作中遇到count(*)、count(1)、count(col) ,可能会让你分不清楚,都是计数,干嘛这么搞这么多东西。

count 作用

COUNT(expression):返回查询的记录总数,expression 参数是一个字段或者 * 号。

测试

MySQL版本:5.7.29

创建一张用户表,并插入一百万条数据,其中gender字段有五十万行是为null值的

CREATE TABLE `users` (
  `Id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` varchar(32) DEFAULT NULL COMMENT '名称',
  `gender` varchar(20) DEFAULT NULL COMMENT '性别',
  `create_date` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`Id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='用户表';

count(*)

在 MySQL 5.7.18 之前,通过扫描聚集索引来InnoDB处理 语句。SELECT COUNT( *)从 MySQL 5.7.18 开始, 通过遍历最小的可用二级索引来InnoDB处理SELECT COUNT( *)语句,除非索引或优化器提示指示优化器使用不同的索引。如果二级索引不存在,则扫描聚集索引。
大概意思就是有二级索引的情况下就使用二级索引,如果有多个二级索引优先选择最小的那个二级索引来降低成本,没有二级索引使用聚集索引。

下面通过测试来验证这些观点。

首先,在只有Id这一个主键索引的情况下查询执行计划,

一文搞清楚MySQL count(*)、count(1)、count(col)区别

可以看到,type是index也就是使用了索引,key是PRIMARY就是使用了主键索引,key_len=8。

其次在name字段上加上索引,再次使用执行计划查看

一文搞清楚MySQL count(*)、count(1)、count(col)区别

可以看到同样使用了索引,只不过索引用的是name字段的索引,key_len=99。

然后在保留name字段索引的情况下给create_date字段也加上索引,再次查看执行计划

一文搞清楚MySQL count(*)、count(1)、count(col)区别

可以看到这次使用的是create_date字段的索引了,key_len=6。

不管上述是使用了哪个索引,其最后查询到的总行数都是一百万条,无论它们是否包含 NULL值。

count(1)

count(1) 和count(*) 执行查询结果一样,最终也是返回一百万条数据,无论它们是否包含 NULL值。

count(col)

count(col) 统计某一列的值,又分为三种情况:

count(id): 统计id

和count(*) 执行查询结果也是一样,最终也是返回一百万条数据.

count(index col):统计带索引的字段

以count(name)进行查询,执行计划如下:

一文搞清楚MySQL count(*)、count(1)、count(col)区别

可以看到用的是索引字段进行统计,索引也命中了。
把一列中的name字段置为NULL,再进行count查询,结果返回999999

一文搞清楚MySQL count(*)、count(1)、count(col)区别

再把这列的NULL值置为空字符串,再进行count查询,结果返回1000000

一文搞清楚MySQL count(*)、count(1)、count(col)区别

所以,综上简单的使用索引字段统计行数能够命中索引,并且只统计不为NULL值的行数。

count(normal col):统计不带索引的字段

统计不带索引的字段的话就不会使用索引,而且也是只统计不为NULL值的行数。

一文搞清楚MySQL count(*)、count(1)、count(col)区别

count(1)和count(*)取舍

之前也不知道在哪看到的或听说的,count(1) 比count(*) 效率高,这是错误的认知,官网上有这么一句话,InnoDB handles SELECT COUNT( *) and SELECT COUNT(1) operations in the same way. There is no performance difference.
翻译过来就是,InnoDB以同样的方式处理SELECT COUNT( *)和SELECT COUNT(1) 操作,没有性能差异。

对于MyISAM表, 如果从一个表中检索,没有检索到其他列并且没有 子句,COUNT(*)则优化为非常快速地返回 ,此优化仅适用于MyISAM 表,因为为此存储引擎存储了准确的行数,并且可以非常快速地访问。 COUNT(1)仅当第一列定义为 时才进行相同的优化NOT NULL。----来自MySQL官网
这些优化都是建立在没有where 和 group by的前提下的。

阿里开发规范中也提到

一文搞清楚MySQL count(*)、count(1)、count(col)区别

所以在开发中能用count(*) 就用count( *).

总结

count(*)、count(1)、count(id):返回查询的记录总数,无论字段是否包含空值,且count( )和count(1)效率是一样的,没差别,通过上面的执行计划可以推断count(id) 和count()、count(1) 效率应该也是一样的或者说是很接近,有兴趣的可以测试一下。
对统计带非主键索引和不带索引的字段进行统计的时候都是统计不为NULL的行数。

到此这篇关于一文搞清楚MySQL count(*)、count(1)、count(col)区别 的文章就介绍到这了,更多相关MySQL count(*),count(1),count(col)内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL update set 和 and的区别
May 08 MySQL
my.ini优化mysql数据库性能的十个参数(推荐)
May 26 MySQL
MySQL高速缓存启动方法及参数详解(query_cache_size)
Jul 01 MySQL
Mysql忘记密码解决方法
Feb 12 MySQL
Mysql Innodb存储引擎之索引与算法
Feb 15 MySQL
利用JuiceFS使MySQL 备份验证性能提升 10 倍
Mar 17 MySQL
MySQL磁盘碎片整理实例演示
Apr 03 MySQL
Mysql 数据库中的 redo log 和 binlog 写入策略
Apr 26 MySQL
详细介绍MySQL中limit和offset的用法
May 06 MySQL
MySQL中order by的执行过程
Jun 05 MySQL
Mysql中的触发器定义及语法介绍
Jun 25 MySQL
MySQL count(*)统计总数问题汇总
Sep 23 MySQL
SQL注入篇学习之盲注/宽字节注入
MySQL为数据表建立索引的原则详解
Mar 03 #MySQL
MySQL数据库完全卸载的方法
千万级用户系统SQL调优实战分享
Mar 03 #MySQL
解析MySQL索引的作用
Arthas排查Kubernetes中应用频繁挂掉重启异常
Feb 28 #MySQL
一文搞懂MySQL索引页结构
You might like
第六节 访问属性和方法 [6]
2006/10/09 PHP
PHP面向对象的使用教程 简单数据库连接
2006/11/25 PHP
PHP连接MySQL的2种方法小结以及防止乱码
2014/03/11 PHP
什么是PEAR?什么是PECL?PHP中两个容易混淆的概念解释
2015/07/01 PHP
jquery+thinkphp实现跨域抓取数据的方法
2016/10/15 PHP
PHP一个简单的无需刷新爬虫
2019/01/05 PHP
Thinkphp极验滑动验证码实现步骤解析
2020/11/24 PHP
Javascript 判断函数类型完美解决方案
2009/09/02 Javascript
javascript采用数组实现tab菜单切换效果
2012/12/12 Javascript
javascript每日必学之继承
2016/02/23 Javascript
Bootstrap3制作图片轮播效果
2016/05/12 Javascript
浅谈Nodejs应用主文件index.js
2016/08/28 NodeJs
详解js前端代码异常监控
2017/01/11 Javascript
深入学习 JavaScript中的函数调用
2017/03/23 Javascript
关于js对textarea换行符的处理方法浅析
2018/08/03 Javascript
JavaScript中引用vs复制示例详析
2018/12/06 Javascript
bootstrap-table+treegrid实现树形表格
2019/07/26 Javascript
解决一个微信号同时支持多个环境网页授权问题
2019/08/07 Javascript
在SAE上部署Python的Django框架的一些问题汇总
2015/05/30 Python
Python使用getpass库读取密码的示例
2017/10/10 Python
对python中数组的del,remove,pop区别详解
2018/11/07 Python
Python+OpenCV图片局部区域像素值处理改进版详解
2019/01/23 Python
Python PyCharm如何进行断点调试
2019/07/05 Python
django 基于中间件实现限制ip频繁访问过程详解
2019/07/30 Python
Centos7下源码安装Python3 及shell 脚本自动安装Python3的教程
2020/03/07 Python
Keras预训练的ImageNet模型实现分类操作
2020/07/07 Python
推荐一些比较有用的css3新属性
2014/11/11 HTML / CSS
html5 的a标签 Href 拨电话的写法
2013/11/04 HTML / CSS
美国尼曼百货官网:Neiman Marcus
2019/09/05 全球购物
创业计划书的内容步骤和要领
2014/01/04 职场文书
园林技术个人的自我评价
2014/01/08 职场文书
英语一分钟演讲稿
2014/04/29 职场文书
2014年副班长工作总结
2014/12/10 职场文书
就业推荐表院系意见
2015/06/05 职场文书
2016年3月份红领巾广播稿
2015/12/21 职场文书
Python matplotlib绘制雷达图
2022/04/13 Python