分享一波:程序员赚外快-必看的巅峰干货

前言

前段时间关于统计数量的sql问题和朋友进行了讨论,网上关于这三种查询方式说法不一,主要有以下两种说法。

count(*) = count(主键) > count(1)
count(主键) > count(*) > count(1)

今天对这三种方式进行探究。

数据库为mysql 5.7.12,引擎为InnoDB。

建表

CREATE TABLE user (
id int(32) NOT NULL AUTO_INCREMENT,
name varchar(500) DEFAULT NULL COMMENT ‘姓名’,
deleted int(2) NOT NULL DEFAULT ‘1’ COMMENT ‘逻辑删除’,
created_date datetime DEFAULT NULL COMMENT ‘创建时间’,
created_by varchar(255) DEFAULT NULL,
update_date datetime DEFAULT NULL,
update_by varchar(255) DEFAULT NULL,
version int(11) NOT NULL DEFAULT ‘1’ COMMENT ‘乐观锁’,
PRIMARY KEY (id) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1502726 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT=‘用户表’;

循环插入150万条数据。

DROP PROCEDURE
IF
EXISTS proc_initData;
DELIMITER $
CREATE PROCEDURE proc_initData () BEGIN
DECLARE
i INT DEFAULT 1;
WHILE
i <= 5000000 DO
INSERT INTO user ( name, created_date, update_date )
VALUES
( ‘哈哈哈啊哈哈哈’, NOW(), NOW() );

 SET i = i + 1;END WHILE;

END $ CALL proc_initData ();

这里需要使用到mysql的explain关键字,对count(1),count(*),count(id),count(name)分别查看性能

explain select count(1) from user
explain select count(*) from user
explain select count(id) from user
explain select count(name) from user

可以看出,select count(1)、count(*)、count(id)的执行计划是一毛一样的。多次执行取平均值,三者的性能也是非常趋近,因此可以认为三者性能相同。这里我加了个count(name)进行对比,并将最后30万条数据的name置空,可以看出性能有明显的差别。

mysql底层对count查询做了优化,当mysql确定count中的列名不为空时,实际上就是在统计行数。那么mysql内部会将count(列名)优化为count(*) —— 出自《高性能MySQL》一书

也就是说count(1)和count(主键字段)还是要优化到count()的,而如果只是统计某个列,只要该列不为空,无论是否为索引,都会被优化为count(),因此三者性能并无任何差异。官方文档对其也进行了解释。

InnoDB handles SELECT COUNT(*) and SELECT COUNT(1) operations in the same way. There is no performance difference.

https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_count

至此,事实上并未解决关于这个问题的疑惑。上面的内容都在强调“Mysql”,就是说,上面的验证可能仅对MySql有效,其他的数据库可能未必会对count语句进行优化。因此我又通过SQLServer去验证。

因为我本地并没有安装SQLServer,因此我是直接使用公司的开发库进行验证,这里不方便截图,直接说明一下200万条数据验证结果。

列名为主键,count(列名)会比count(1)快
列名不为主键,count(1)会比count(列名)快
如果表多个列并且没有主键,则 count(1) 的执行效率优于 count(*)
如果有主键,则 select count(主键)的执行效率是最优的
如果表只有一个字段,则 select count(*)最优。

可见,在SQLServer中,count(*)的性能并没有count(主键)高。
结语

根据上面对两个数据库的验证得出结论:不说是什么数据库都是耍流氓!SQL标准只提供了count这个内置函数,所有的数据库需要遵循这个标准,但是不同的数据库对于count的处理不同。在mysql中建议写count(*),而在SQLServer中建议写count(主键),在PostgreSql以及其他数据库中并未对其进行验证

分享一波:程序员赚外快-必看的巅峰干货

如果以上内容对你觉得有用,并想获取更多的赚钱方式和免费的技术教程

请关注微信公众号:HB荷包

一个能让你学习技术和赚钱方法的公众号,持续更新

count(1),count(*),count(主键) 性能对比及辟谣相关推荐

  1. mysql innodb 主键,Mysql InnoDB 引擎 主键性能

    前些天看到网上有人说:Mysql InnoDB 引擎 主键不适合用UUID , 若要用UUID的话可考虑用 自增ID做物理主键,UUID做逻辑主键. 带着以上问题,本人做了如下测试: 先自报测试环境: ...

  2. MySQL 主键性能解析

    目录 InnoDB基本知识 B+树介绍 性能解析 占用空间 主键长度 查询性能 磁盘随机IO 写入性能 磁盘随机IO 页分裂 页合并 总结 注: 默认存储引擎InnoDB InnoDB基本知识 在 I ...

  3. mysql 隐式主键_MySQL中复合主键性能的缺点

    我们有一个表,该表具有由三个字段组成的复合主键(在MySQL 5.1中是这样). 该表上每秒有近200个插入和200个选择,并且表的大小约为100万行,并且还在不断增加. 我的问题是:"复合 ...

  4. mysql uuid 性能_mysql InnoDB UUID 主键 性能优化【性能分析篇】.md

    Benchmarking 主键字段的三种存储方式 events_uuid – UUID binary(16) PRIMARY KEY events_int – 自增序列bigint(20) NOT N ...

  5. mysql复合主键优缺点_MySQL中的复合主键性能缺陷

    INSERT 和 UPDATE 性能变化很小: (INT) 和 (INT, INT) 键几乎相同 . SELECT 复合 PRIMARY KEY 的性能取决于很多因素 . 如果您的表是 InnoDB ...

  6. mysql 求count和_MySQL的统计总数count(*)与count(id)或count(字段)的之间的各自效率性能对比...

    执行效果: 1.  count(1) and count(*) 当表的数据量大些时,对表作分析之后,使用count(1)还要比使用count(*)用时多了! 从执行计划来看,count(1)和coun ...

  7. select count(1) 、select count(*) 、select count(字段)的区别、及性能

    select count(*) from teacher; //11 select count(1) from teacher; //11 select count(id) from teacher; ...

  8. sql中count(1)、count(*)和count(字段名)的区别

    执行效果上:   count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL. count(1)包括了忽略所有列,用1代表代码行,在统计结果的时候,不会忽略列值为NULL . ...

  9. mysql count 1_高性能MySQL count(1)与count(*)的差别

    -------------------------------------------------------------------------------------------------第一篇 ...

最新文章

  1. 使用python实现对于chineseocr的API调用
  2. 第三篇 层次类非线性表的编程实验 第10章 应用经典二叉树编程
  3. c++ gdb 绑定源码_gdb调试g++ -g生成文件,list后不能看到源代码
  4. FusionCharts 分类以及各个属性参数列表
  5. TCP粘包原因及解决办法
  6. jclasslib的使用
  7. 从零开始的小白pr学习之旅--day2 数字后端流程(一)
  8. Linux操作命令分类详解 - 目录文件(二)
  9. 【3分钟带你学】Ajax
  10. Android车载蓝牙相关开发4:蓝牙电话操作器BluetoothHeadsetClient
  11. gc java_java内存管理以及GC
  12. 标准成本和实际成本的比较
  13. Idea 链接mysql数据库失败 Schemas中为空
  14. turnserver 搭建
  15. Rust的前景怎么样?值不值的学—Rust对比、特色和理念
  16. EasyDarwin开源流媒体服务器内存管理优化
  17. 中国软件开发者(研究生)的人生规划(转自天涯虚拟社区)
  18. zabbix接合grafana画图
  19. Html 下拉框 复选
  20. SqlSugar函数查询

热门文章

  1. mysql日志文件的类型和作用_Mysql日志文件和日志类型介绍_MySQL
  2. 在linux中编写shell脚本文件,如何编写简单的Shell脚本(Script)文件之Linux的基本操作...
  3. redis分布式锁小试
  4. Linux启动更新命令,Linux更新和查询命令chkconfig详细介绍
  5. mysql with as 用法_英语语法丨英语中just的用法总结,你掌握了吗?
  6. xss原理和注入类型
  7. 海南大学计算机原理,海南大学微机原理课件 第一章 计算机基础知识
  8. 潜流式湿地计算_人工湿地计算书
  9. php mysql 图像_php-向/从MySQL数据库插入/查看图像
  10. 计算机专业知识是什么范围,计算机基础知识考题