一文搞清楚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 相关文章推荐
低版本Druid连接池+MySQL驱动8.0导致线程阻塞、性能受限
Jul 01 MySQL
SQL之各种join小结详细讲解
Aug 04 MySQL
SQL语法CONSTRAINT约束操作详情
Jan 18 MySQL
详解MySql中InnoDB存储引擎中的各种锁
Feb 12 MySQL
mysql聚集索引、辅助索引、覆盖索引、联合索引的使用
Feb 12 MySQL
MySQL七大JOIN的具体使用
Feb 28 MySQL
Mysql如何实现不存在则插入,存在则更新
Mar 25 MySQL
MySql重置root密码 --skip-grant-tables
Apr 11 MySQL
详解Mysql事务并发(脏读、不可重复读、幻读)
Apr 29 MySQL
Mysql开启外网访问
May 15 MySQL
MySQL数据库配置信息查看与修改方法详解
Jun 25 MySQL
SQLServer常见数学函数梳理总结
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/10/09 PHP
推荐一篇入门级的Class文章
2007/03/19 PHP
php实现的仿阿里巴巴实现同类产品翻页
2009/12/11 PHP
使用PHP 5.0创建图形的巧妙方法
2010/10/12 PHP
php中过滤非法字符的具体实现
2013/10/29 PHP
解密ThinkPHP3.1.2版本之模块和操作映射
2014/06/19 PHP
PHP array_reverse() 函数原理及实例解析
2020/07/14 PHP
Javascript学习笔记6 prototype的提出
2010/01/11 Javascript
解决js中window.open弹出的是上次的缓存页面问题
2013/12/29 Javascript
js特殊字符过滤的示例代码
2014/03/05 Javascript
js无刷新操作table的行和列
2014/03/27 Javascript
jQuery实现鼠标经过事件的延时处理效果
2020/08/20 Javascript
jQuery中的ready函数与window.onload谁先执行
2016/06/21 Javascript
jQuery下拉菜单的实现代码
2016/11/03 Javascript
详解Webstorm 下的Angular2.0开发之路(图文)
2018/12/06 Javascript
vue-router 起步步骤详解
2019/03/26 Javascript
jQuery 查找元素操作实例小结
2019/10/02 jQuery
微信小程序中的上拉、下拉菜单功能
2020/03/13 Javascript
[02:04]2018DOTA2亚洲邀请赛Secret赛前采访
2018/04/03 DOTA
[09:40]DAC2018 4.5 SOLO赛 MidOne vs Miracle
2018/04/06 DOTA
[47:03]完美世界DOTA2联赛PWL S3 Galaxy Racer vs Phoenix 第二场 12.10
2020/12/13 DOTA
[47:52]DOTA2-DPC中国联赛正赛 iG vs LBZS BO3 第二场 3月4日
2021/03/11 DOTA
深入浅析Python2.x和3.x版本的主要区别
2018/11/30 Python
Python 实现向word(docx)中输出
2020/02/13 Python
通过自学python能找到工作吗
2020/06/21 Python
纯CSS3实现鼠标悬停提示气泡效果
2014/02/28 HTML / CSS
HTML5 Canvas中使用路径描画二阶、三阶贝塞尔曲线
2015/01/01 HTML / CSS
Oracle快照(snapshot)
2015/03/13 面试题
门卫人员岗位职责
2013/12/24 职场文书
心得体会的写法
2014/09/05 职场文书
合作协议书模板
2014/10/10 职场文书
关于安全的广播稿
2014/10/23 职场文书
2015年入党积极分子培养考察意见
2015/08/12 职场文书
《月光曲》教学反思
2016/02/16 职场文书
pytorch 使用半精度模型部署的操作
2021/05/24 Python
CSS 鼠标选中文字后改变背景色的实现代码
2023/05/21 HTML / CSS