一文搞清楚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 - 常用函数 每天积极向上
Apr 05 MySQL
Mysql基础之常见函数
Apr 22 MySQL
Navicat连接MySQL错误描述分析
Jun 02 MySQL
MySQL 时间类型的选择
Jun 05 MySQL
MySQL8.0.18配置多主一从
Jun 21 MySQL
sql注入教程之类型以及提交注入
Aug 02 MySQL
mysql事务对效率的影响分析总结
Oct 24 MySQL
MySQL 数据类型详情
Nov 11 MySQL
面试提问mysql一张表到底能存多少数据
Mar 13 MySQL
MySQL 执行数据库更新update操作的时候数据库卡死了
May 02 MySQL
Mysql表数据比较大情况下修改添加字段的方法实例
Jun 28 MySQL
MySQL性能指标TPS+QPS+IOPS压测
Aug 05 MySQL
SQL注入篇学习之盲注/宽字节注入
MySQL为数据表建立索引的原则详解
Mar 03 #MySQL
MySQL数据库完全卸载的方法
千万级用户系统SQL调优实战分享
Mar 03 #MySQL
解析MySQL索引的作用
Arthas排查Kubernetes中应用频繁挂掉重启异常
Feb 28 #MySQL
一文搞懂MySQL索引页结构
You might like
php中看实例学正则表达式
2006/12/25 PHP
PHP 递归效率分析
2009/11/24 PHP
《PHP编程最快明白》第六讲:Mysql数据库操作
2010/11/01 PHP
php加密解密字符串示例
2016/10/13 PHP
YII框架实现自定义第三方扩展操作示例
2019/04/26 PHP
详解no input file specified 三种解决方法
2019/11/29 PHP
Jquery Validation插件防止重复提交表单的解决方法
2010/03/05 Javascript
nodejs npm包管理的配置方法及常用命令介绍
2014/06/05 NodeJs
JQuery实现DIV其他动画效果的简单实例
2016/09/18 Javascript
JavaScript使用Range调色及透明度实例
2016/09/25 Javascript
详解使用JS如何制作简单的ASCII图与单极图
2017/03/31 Javascript
基于 flexible 的 Vue 组件:Toast -- 显示框效果
2017/12/26 Javascript
小程序开发踩坑:页面窗口定位(相对于浏览器定位)(推荐)
2019/04/25 Javascript
微信sdk实现禁止微信分享(使用原生php实现)
2019/11/15 Javascript
谈谈Python进行验证码识别的一些想法
2016/01/25 Python
浅谈python中拼接路径os.path.join斜杠的问题
2018/10/23 Python
PyQt5的安装配置过程,将ui文件转为py文件后显示窗口的实例
2019/06/19 Python
PyQt5基本控件使用详解:单选按钮、复选框、下拉框
2019/08/05 Python
python实现在一个画布上画多个子图
2020/01/19 Python
python随机生成大小写字母数字混合密码(仅20行代码)
2020/02/01 Python
Kears 使用:通过回调函数保存最佳准确率下的模型操作
2020/06/17 Python
Python爬虫之Spider类用法简单介绍
2020/08/04 Python
python多线程爬取西刺代理的示例代码
2021/01/30 Python
用CSS3绘制三角形的简单方法
2015/07/17 HTML / CSS
实例教程 利用html5和css3打造一款创意404页面
2014/10/20 HTML / CSS
HTML5自定义属性前缀data-及dataset的使用方法(html5 新特性)
2017/08/24 HTML / CSS
Staples美国官方网站:办公用品一站式采购
2016/07/28 全球购物
韩国乐天网上商城:Lotte iMall
2021/02/03 全球购物
医生实习工作总结的自我评价
2013/09/27 职场文书
医药专业应届毕业生求职信范文
2014/01/01 职场文书
《长江之歌》教学反思
2014/04/17 职场文书
工会文体活动总结
2015/05/07 职场文书
信用卡工作证明范本
2015/06/19 职场文书
提升Nginx性能的一些建议
2021/03/31 Servers
CSS3 实现NES游戏机的示例代码
2021/04/21 HTML / CSS
MySQL 数据丢失排查案例
2021/05/08 MySQL