【MySQL】- 09 Select Count

news2024/11/25 14:39:28

【MySQL】- 09 Select Count

    • 1认识COUNT
    • 2 COUNT(列名)、COUNT(常量)和COUNT(*)之间的区别
    • 3 COUNT(*)的优化
    • 4 COUNT(*)和COUNT(1)
    • 5 COUNT(字段)
    • 总结

        数据库查询相信很多人都不陌生,所有经常有人调侃程序员就是CRUD专员,这所谓的CRUD指的就是数据库的增删改查。

        在数据库的增删改查操作中,使用最频繁的就是查询操作。而在所有查询操作中,统计数量操作更是经常被用到。

        关于数据库中行数统计,无论是MySQL还是Oracle,都有一个函数可以使用,那就是COUNT。

        但是,就是这个常用的COUNT函数,却暗藏着很多玄机,尤其是在面试的时候,一不小心就会被虐。不信的话请尝试回答下以下问题:

  1. COUNT有几种用法?
  2. COUNT(字段名)和COUNT()的查询结果有什么不同?
  3. COUNT(1)和COUNT()之间有什么不同?
  4. COUNT(1)和COUNT()之间的效率哪个更高?
  5. 为什么《阿里巴巴Java开发手册》建议使用COUNT()
  6. MySQL的MyISAM引擎对COUNT()做了哪些优化?
  7. MySQL的InnoDB引擎对COUNT()做了哪些优化?
  8. 上面提到的MySQL对COUNT()做的优化,有一个关键的前提是什么?
  9. SELECT COUNT() 的时候,加不加where条件有差别吗?
  10. COUNT(*)、COUNT(1)和COUNT(字段名)的执行过程是怎样的?

以上10道题,如果您可以全部准确无误的回答的话,那说明你真的很了解COUNT函数了,如果有哪些知识点是不了解的,那么本文正好可以帮你答疑解惑。

1认识COUNT

关于COUNT函数,在MySQL官网中有详细介绍:
在这里插入图片描述

简单翻译一下:

1、COUNT(expr) ,返回SELECT语句检索的行中expr的值不为NULL的数量。结果是一个BIGINT值。

2、如果查询结果没有命中任何记录,则返回0

3、但是,值得注意的是,COUNT(*) 的统计结果中,会包含值为NULL的行数。

即以下表记录

create table #bla(id int,id2 int)
insert #bla values(null,null)
insert #bla values(1,null)
insert #bla values(null,1)
insert #bla values(1,null)
insert #bla values(null,1)
insert #bla values(1,null)
insert #bla values(null,null)

使用语句count(*),count(id),count(id2)查询结果如下:

select count(*),count(id),count(id2)
from #bla
results 7 3 2

除了COUNT(id)COUNT(*)以外,还可以使用COUNT(常量)(如COUNT(1))来统计行数,那么这三条SQL语句有什么区别呢?到底哪种效率更高呢?为什么《阿里巴巴Java开发手册》中强制要求不让使用 COUNT(列名)COUNT(常量)来替代 COUNT(*)呢?

【强制】不要使用count(列名)count(常量)来替代count(*)count(*)是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。

说明:count(*)会统计值为NULL的行,而count(列名)不回统计此列为NULL值的行。

2 COUNT(列名)、COUNT(常量)和COUNT(*)之间的区别

前面我们提到过COUNT(expr)用于做行数统计,统计的是expr不为NULL的行数,那么COUNT(列名)COUNT(常量)COUNT(*)这三种语法中,expr分别是列名常量*

那么列名常量*这三个条件中,常量 是一个固定值,肯定不为NULL。*可以理解为查询整行,所以肯定也不为NULL,那么就只有列名的查询结果有可能是NULL了。

所以, COUNT(常量)COUNT(\*)表示的是直接查询符合条件的数据库表的行数。而COUNT(列名)表示的是查询符合条件的列的值不为NULL的行数。

除了查询得到结果集有区别之外,COUNT(*)相比COUNT(常量)COUNT(列名)来讲,COUNT(*)是SQL92定义的标准统计行数的语法,因为他是标准语法,所以MySQL数据库对他进行过很多优化。

SQL92,是数据库的一个ANSI/ISO标准。它定义了一种语言(SQL)以及数据库的行为(事务、隔离级别等)。

3 COUNT(*)的优化

前面提到了COUNT(*)是SQL92定义的标准统计行数的语法,所以MySQL数据库对他进行过很多优化。那么,具体都做过哪些事情呢?

这里的介绍要区分不同的执行引擎。MySQL中比较常用的执行引擎就是InnoDB和MyISAM。

MyISAM和InnoDB有很多区别,其中有一个关键的区别和我们接下来要介绍的COUNT(*)有关,那就是**MyISAM不支持事务,MyISAM中的锁是表级锁;**而InnoDB支持事务,并且支持行级锁。

因为MyISAM的锁是表级锁,所以同一张表上面的操作需要串行进行,所以,MyISAM做了一个简单的优化,那就是它可以把表的总行数单独记录下来,如果从一张表中使用COUNT(*)进行查询的时候,可以直接返回这个记录下来的数值就可以了,当然,前提是不能有where条件。

MyISAM之所以可以把表中的总行数记录下来供COUNT(*)查询使用,那是因为MyISAM数据库是表级锁,不会有并发的数据库行数修改,所以查询得到的行数是准确的。

但是,对于InnoDB来说,就不能做这种缓存操作了,因为InnoDB支持事务,其中大部分操作都是行级锁,所以可能表的行数可能会被并发修改,那么缓存记录下来的总行数就不准确了。

但是,InnoDB还是针对COUNT(*)语句做了些优化的。

在InnoDB中,使用COUNT(*)查询行数的时候,不可避免的要进行扫表了,那么,就可以在扫表过程中下功夫来优化效率了。

从MySQL 8.0.13开始,针对InnoDB的SELECT COUNT(*) FROM tbl_name语句,确实在扫表的过程中做了一些优化。前提是查询语句中不包含WHERE或GROUP BY等条件。

我们知道,COUNT(*)的目的只是为了统计总行数,所以,他根本不关心自己查到的具体值,所以,他如果能够在扫表的过程中,选择一个成本较低的索引进行的话,那就可以大大节省时间。

我们知道,InnoDB中索引分为聚簇索引(主键索引)和非聚簇索引(非主键索引),聚簇索引的叶子节点中保存的是整行记录,而非聚簇索引的叶子节点中保存的是该行记录的主键的值。

所以,相比之下,非聚簇索引要比聚簇索引小很多,所以**MySQL会优先选择最小的非聚簇索引来扫表。**所以,当我们建表的时候,除了主键索引以外,创建一个非主键索引还是有必要的。

至此,我们介绍完了MySQL数据库对于COUNT(*)的优化,这些优化的前提都是查询语句中不包含WHERE以及GROUP BY条件。

4 COUNT(*)和COUNT(1)

介绍完了COUNT(*),接下来看看COUNT(1),对于,这二者到底有没有区别,网上的说法众说纷纭。

有的说COUNT(*)执行时会转换成COUNT(1),所以COUNT(1)少了转换步骤,所以更快。

还有的说,因为MySQL针对COUNT(*)做了特殊优化,所以COUNT(*)更快。

那么,到底哪种说法是对的呢?看下MySQL官方文档是怎么说的:

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

画重点:same way , no performance difference所以,对于COUNT(1)和COUNT(*),MySQL的优化是完全一样的,根本不存在谁比谁快!

那既然COUNT(*)COUNT(1)一样,建议用哪个呢?

建议使用COUNT(*)!因为这个是SQL92定义的标准统计行数的语法,而且本文只是基于MySQL做了分析,关于Oracle中的这个问题,也是众说纷纭的呢。

5 COUNT(字段)

最后,就是我们一直还没提到的COUNT(字段),他的查询就比较简单粗暴了,就是进行全表扫描,然后判断指定字段的值是不是为NULL,不为NULL则累加。

相比COUNT(*)COUNT(字段)多了一个步骤就是判断所查询的字段是否为NULL,所以他的性能要比COUNT(*)慢。

总结

        本文介绍了COUNT函数的用法,主要用于统计表行数。主要用法有COUNT(*)COUNT(字段)COUNT(1)

        因为COUNT(*)是SQL92定义的标准统计行数的语法,所以MySQL对他进行了很多优化,MyISAM中会直接把表的总行数单独记录下来供COUNT(*)查询,而InnoDB则会在扫表的时候选择最小的索引来降低成本。当然,这些优化的前提都是没有进行where和group的条件查询。

        在InnoDB中COUNT(*)COUNT(1)实现上没有区别,而且效率一样,但是COUNT(字段)需要进行字段的非NULL判断,所以效率会低一些。

        因为COUNT(*)是SQL92定义的标准统计行数的语法,并且效率高,所以请直接使用COUNT(*)查询表的行数!

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

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

相关文章

[python] 过年燃放烟花

目录 新年祝福语 一、作品展示 二、作品所用资源 三、代码与资源说明 四、代码库 五、完整代码 六、总结 新年祝福语 岁月总是悄然流转,让人感叹时间的飞逝,转眼间又快到了中国传统的新年(龙年)。 回首过去&#xf…

VMWare下载安装(包含Window是和Mac)

VMWare下载安装(包含Window是和Mac) 文章目录 VMWare下载安装(包含Window是和Mac)一、windows下载VMWare①:下载01:网盘下载02:官方下载 ②:安装③:密钥 二、Mac下载VMWa…

2.3作业

作业要求&#xff1a; 程序代码&#xff1a; #include<stdlib.h> #include<string.h> #include<stdio.h> typedef struct node //定义链表节点结构体&#xff1a;数据域、指针域 {int data;struct node *next; }*linklist;linklist create_node()//创建新节…

【解刊】顶级IEEE(trans),一审极快!对国人审稿友好,大咖教授投稿之选

计算机类 • 高分快刊 今天带来IEEE旗下计算机领域高分快刊&#xff0c;审稿速度快&#xff0c;期刊质量高&#xff0c;审稿过程友好。如有投稿意向可重点关注&#xff1a; 01 期刊简介 IEEE Transactions on Network Science and Engineering ✅出版社&#xff1a;IEEE ✅I…

缓存组件Caffeine的使用

caffeine是一个高性能的缓存组件&#xff0c;在需要缓存数据&#xff0c;但数据量不算太大&#xff0c;不想引入redis的时候&#xff0c;caffeine就是一个不错的选择。可以把caffeine理解为一个简单的redis。 1、导入依赖 <!-- https://mvnrepository.com/artifact/com.git…

力扣题目训练(7)

2024年1月31日力扣题目训练 2024年1月31日力扣题目训练387. 字符串中的第一个唯一字符389. 找不同401. 二进制手表109. 有序链表转换二叉搜索树114. 二叉树展开为链表52. N 皇后 II 2024年1月31日力扣题目训练 2024年1月31日第七天编程训练&#xff0c;今天主要是进行一些题训…

小型内衣洗衣机什么牌子好?家用小型洗衣机推荐

内衣裤作为我们日常必备的贴身衣物&#xff0c;所以对卫生方面的要求也比较高&#xff0c;但对许多人们而言&#xff0c;对内衣裤进行清洗是一项相当繁琐的事情&#xff0c;主要是因为并不能直接把内衣裤放入大型洗衣机里和其它衣服混合洗&#xff0c;所以大多数用户都会自己动…

2024美赛数学建模C题完整论文教学(含十几个处理后数据表格及python代码)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了数学建模美赛本次C题目Momentum in Tennis完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。 C论文共49页&…

程序员想告赢开发商一户一表违约(终审判决)——铁拳迟到会打到每一个人...

二审的结果并没有出乎我的意料&#xff1a;维持原判。所以是我输了这场官司。 只是我输得非常不服气。 在二审中&#xff0c;我变换思路&#xff0c;以以下思路进行辩论&#xff1a; 1. 从“正式供电”方向&#xff0c;使用国家国标和法律法规证明小区目前非正式用电&#xff0…

三维模型的面数、段数、曲面必须进行精简优化?使用什么技术或手段实现最优解呢?

大师重建设置里面可以选择是否对三角网进行简化。数据简化介绍&#xff1a;针对弱纹理区域的三角网&#xff0c;简化面的智能识别处理。 重建大师是一款专为超大规模实景三维数据生产而设计的集群并行处理软件&#xff0c;输入倾斜照片&#xff0c;激光点云&#xff0c;POS信息…

关于服务器解析A记录和CNAME记录的分析

内容提要: 大致讲下理解,dns域名解析这一块 0 . 问题来源 最近搞了一个七牛云上传,然后需要配置融合cdn加速,也就是可以加速域名,中间有一部需要CNAME 域名,也就是将七牛云提供的域名CNAME一下,查阅资料其实就是起一个别名,好访问而已. 方便我们访问云存储,达到加速的效果. …

ONLYOFFICE 文档 8.0 现已发布:PDF 表单、RTL、单变量求解、图表向导、插件界面设计等更新

我们最新版本的在线编辑器现已推出&#xff0c;为整个套件优化了多项功能。阅读下文&#xff0c;了解详细更新内容。 什么是 ONLYOFFICE 文档 ONLYOFFICE 文档是一款开源的办公套件&#xff0c;由总部位于拉脱维亚的Ascensio System SIA开发。它支持处理文本文档、电子表格、演…

1216 - 数塔问题

题目 有如下所示的数塔&#xff0c;要求从底层走到顶层&#xff0c;若每一步只能走到相邻的结点&#xff0c;则经过的结点的数字之和最大是多少&#xff1f; 输入 输入数据首先包括一个整数整数 N (1≤N≤100)&#xff0c;表示数塔的高度&#xff0c;接下来用 N 行数字表示数…

力扣热门100题刷题笔记 - 5.最长回文子串

力扣热门100题 - 5.最长回文子串 题目链接&#xff1a;5. 最长回文子串 题目描述&#xff1a; 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。示例&#xff1a; 输入&#xff1a;s "…

FFMPEG推流到B站直播

0、参考 ffmpeg安装参考小弟另外的一个博客&#xff1a;FFmpeg和rtsp服务器搭建视频直播流服务-CSDN博客推流参考&#xff1a;用ffmpeg 做24小时推流直播_哔哩哔哩_bilibili 一、获取b站直播码 点击开始直播后&#xff0c;会出现以下的画面 二、ffmpeg进行直播推流 ffmpeg -r…

python常用pandas函数nlargest / nsmallest及其手动实现

目录 pandas库 Series和DataFrame nlargest和nsmallest 用法示例 代替方法 手动实现 模拟代码 pandas库 是Python中一个非常强大的数据处理库&#xff0c;提供了高效的数据分析方法和数据结构。它特别适用于处理具有关系型数据或带标签数据的情况&#xff0c;同时在时间…

速过计算机二级python——第六讲:文件操作

第六讲:文件操作 文件夹创建文件夹移动文件夹复制文件夹删除文件夹文件操作文件读取文件写入文件文件夹 创建文件夹 定义创建文件夹函数:chmk_path()定义一个函数 chmk_path(),这个函数的功能是创建文件夹。 首先需要导入操作系统接口模块——os 模块,这个模块中包含某些函…

Linux校准时间 Centos

Linux校准时间 Centos 首先&#xff0c;确保系统中已经安装了tzdata包。如果没有安装&#xff0c;可以使用以下命令安装&#xff1a; sudo yum install tzdata设置系统时区为上海&#xff1a; sudo timedatectl set-timezone Asia/Shanghai验证时区设置是否生效&#xff1a;…

STM32F407 CAN参数配置 250Kbps

本篇CAN参数适用 芯片型号&#xff1a;STM32F407xx系统时钟&#xff1a;168MHz&#xff0c;CAN挂载总线APB1为42M波 特 率 &#xff1a;250Kpbs引脚使用&#xff1a;TX_PB9&#xff0c;RX_PB8&#xff1b;修改为PA11PA12后&#xff0c;参数不变。 步骤一、打勾开启CAN&#xf…

视频业务像素、带宽、存储空间计算

一、像素和分辨率 分辨率的单位通常是像素&#xff08;或点&#xff09;&#xff0c;用水平像素数乘以垂直像素数来表示。例如&#xff0c;一个分辨率为1920 x 1080的屏幕有1920个水平像素和1080个垂直像素。 总像素分辨率公式运算 例如 1920 x 10802073600总约200万 500W≈…