count(1),count(*),count(主键) 性能对比及辟谣

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

前言

前段时间关于统计数量的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荷包
在这里插入图片描述
一个能让你学习技术和赚钱方法的公众号,持续更新

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/537019.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python与会计的论文_甭管前浪后浪,写完论文的先浪!

原标题&#xff1a;甭管前浪后浪&#xff0c;写完论文的先浪&#xff01;自愿返校已是板上钉钉的事儿了而对于大家的期末考现在也基本上已经通知线上考试如果没有线上考试的话&#xff0c;那就是交论文可是&#xff0c;论文动不动就2000字10%查重毛概、各种选修课等等每一门都是…

git 命令 clone分支的代码

一个项目通常含有很多分支&#xff0c; master分支一般是经过测试&#xff0c;验证没有问题后&#xff0c;代码才会提交到master分支 develop分支&#xff0c;是测试经常拉下来进行测试的分支 直接复制develop分支的git 命令如下&#xff1a; git clone -b develop gitxxx 转载…

String s = new String(123) 究竟创建了几个对象

分享一波:程序员赚外快-必看的巅峰干货 前言 今天上班划水的过程中有人询问到这个问题&#xff0c;网上对于这个问题也有争议&#xff0c;有说创建了一个对象&#xff0c;有说两个&#xff0c;有说三个。 首先说三个的肯定是扯淡了&#xff0c;今天来讨论一下这条语句到底创…

jquery级试题_JS-jQuery练习题面试题

ES5中不能实现继承的关键字A prototypeB callC applyD extends正确答案: D extends //属于ES6不属于常见23种设计模式A 单例B MVCC 观察者D 策略正确答案: B创建型模式&#xff0c;共五种&#xff1a;工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。结构型模式&…

Vue 计算属性与侦听器

这一节我们一起学习 vue 中的计算属性(computed properties)和侦听器(watch)。 在之前&#xff0c;我们学习过 vue 表达式插值&#xff1a; <div id"example">{{ message.split().reverse().join() }} </div> 如果在模板中放入太多的逻辑会让模板过重且难…

程序员到底要不要重复造轮子?

分享一波:程序员赚外快-必看的巅峰干货 关于这个话题&#xff0c;现在这里阐述立场&#xff1a;就公司工作而言&#xff0c;不建议重复造轮子。就个人技术而言&#xff0c;强烈建议造轮子&#xff01; 程序员圈子里流行这么一句话&#xff1a;“不要重复造轮子”。它的原文是…

1582年日历怎么了_【知乎周边】知乎2020年日历开箱+测评

感谢 刘看山 刘看山福利社 知一声 这边知乎朋友赠送的礼物&#xff0c;这边拿到了新的一年2020年知乎的日历。随日历还赠送了一年的盐选会员体验卡&#xff0c;这个福利很特别哈。打开盒子&#xff0c;里面是厚厚的但是却不是很大的一个正方体。侧面写有“有问题的日历”日历内…

Redis集群一致性Hash效果的代码演示

在微服务领域&#xff0c;使用Redis做缓存可并不是一件容易的事情。 像新浪、推特这样的应用&#xff0c;许许多多的热点数据全都存放在Redis这一层&#xff0c;打到DB层的请求并不多&#xff0c;可以说非常依赖缓存了。如果缓存挂掉&#xff0c;流量全部穿透到DB层&#xff0c…

多线程-题

1、进程和线程之间有什么不同&#xff1f; 一个进程是一个独立&#xff08;self contained&#xff09;的运行环境&#xff0c;它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。java运行环境是一个包含了不同的类和程序的单一进程。线程可以被称为轻量级进…

JDK8那些惊为天人的新特性

分享一波:程序员赚外快-必看的巅峰干货 介绍 随着java的发展&#xff0c;越来越多的企业开始使用 java8 版本。Java8 是自 java5之后最重要的版本&#xff0c;这个版本包含语言、编译器、库、工具、JVM等方面的十多个新特性。本次课程将着重学习其中的一些重点特性。 Jdk8新…

mount 安卓system只读_Android如何让system分区可读写(MTK安卓6.0)-阿里云开发者社区...

Android 系统默认情况下&#xff0c;system 分区是只读 mount 的&#xff0c;因为无法进行往里写数据的&#xff0c;可以用 adb 命令 adb remount 重新 mount 一下。也可以通过在板子上&#xff0c;输入以下命令重新mount一下system分区命令使其可读可写。# mount -o remount /…

【数据结构和算法05】 红-黑树(转发)

2019独角兽企业重金招聘Python工程师标准>>> 【数据结构和算法05】 红-黑树&#xff08;看完包懂~&#xff09; 置顶 2016年04月13日 15:50:25 eson_15 阅读数&#xff1a;52681 标签&#xff1a; java数据结构算法红黑树 更多 个人分类&#xff1a; ● 结构算法---…

数据结构与算法——二叉树、堆、优先队列

*************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 七、树 7.1 树 7.1.1 树的定义 树是我们计算机中非常重要的一种数据结构&#xff0c;同时使用树这种数据结构&#xff0c;可以描述现实生活…

android组建之间通信_Android组件化(三)组件之间的通信

介绍在组件化开发的时候&#xff0c;组件之间是相互独立的没有依赖关系&#xff0c;我们不能在使用显示调用来跳转页面了&#xff0c;因为我们组件化的目的之一就是解决模块间的强依赖问题&#xff0c;假如现在要从A业务组件跳转到业务B组件&#xff0c;并且要携带参数跳转&…

继牛津大学后,加大伯克利分校等多家美国高校终止与华为合作

文&#xff0f;AI财经社 唐煜编&#xff0f;嵇国华据 Nature News 报道&#xff0c;在美国相关部门的压力之下&#xff0c;加州大学伯克利分校&#xff08;UC Berkeley&#xff09;近日宣布不再与华为签署新的研究合作&#xff1b;德州大学奥斯丁分校也正在审查自身与华为的关系…

为什么varchar字段长度最好是2的n次方-1

*************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 计算机是二进制计算的&#xff0c;1 bytes 8 bit ,一个字节最多可以代表的数据长度是2的8次方 11111111 在计算机中也就是-128到127。 而var…

运筹学状态转移方程例子_强化学习第4期:H-J-B方程

在上一篇文章中&#xff0c;我们介绍了一种最简单的MDP——s与a都是有限的MDP的求解方法。其中&#xff0c;我们用到了动态规划的思想&#xff0c;并且推出了“策略迭代”、“值迭代”这样的方法。今天&#xff0c;我们要来讲更加一般的最优控制问题——t、a与s都是连续的问题。…

Python之celery的简介与使用

celery的简介 celery是一个基于分布式消息传输的异步任务队列&#xff0c;它专注于实时处理&#xff0c;同时也支持任务调度。它的执行单元为任务&#xff08;task&#xff09;&#xff0c;利用多线程&#xff0c;如Eventlet&#xff0c;gevent等&#xff0c;它们能被并发地执行…

不使用比较运算符如何比较两个数的大小

分享一波:程序员赚外快-必看的巅峰干货 前言 今天在水群的过程中看到有位群员谈论到这个话题&#xff0c;是他找工作过程中某家公司的面试题&#xff08;到底是哪家公司才会出这种没营养的题目刁难别人&#xff09;&#xff0c;有点兴趣&#xff0c;就开始写了。 开搞 想了一…

java占位符填充_Java使用freemark生成word

1、制作模板先用office word做一个模板word文档&#xff0c;${usrName}、${nowDate}占位符 可以使用 office 或者 wps 先创建一个模板表格 &#xff08;替换$部分可以在 模板格式改变之后 在替换xml 格式改了后有些原本的字符会分开&#xff09;2、用office word将模板word另存…