MySQL的COUNT语句,竟然都能被面试官虐的这么惨!?

2023-05-16

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

但是,就是这个常用的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(expr)用于做行数统计,那么COUNT(列名)、 COUNT(常量) 和 COUNT(*)这三种语法中,expr分别指的是列名、 常量 和 *。

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

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

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

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


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条件


COUNT(*)和COUNT(1)

介绍完COUNT(*),接下来看看COUNT(1),对于,这二者到底有没有区别,网上的说法众说纷纭。看下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定义的标准统计行数的语法。


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(*)查询表的行数!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL的COUNT语句,竟然都能被面试官虐的这么惨!? 的相关文章

  • Abort message: ‘FORTIFY: FD_SET: file descriptor 1070 >= FD_SETSIZE 128‘

    问题现象 压力测试骁龙相机 xff0c 发现camera provicer 进程崩溃 无法正常打开相机 xff0c 只有重新启动设备 相关的log xff1a 03 23 08 17 08 592 15634 15634 F DEBUG s
  • 滚动校验(Rolling Checksum)算法

    滚动校验 Rolling Checksum 算法 Rsync中使用了一种滚动检验 Rolling Checksum 算法 xff0c 用于快速计算数据块的检验值 它是一种弱校验算法 xff0c 采用的是Mark Adler的adler 32
  • Android GMS认证总结01

    测试项 失败项 备注 GTS com google android media gts WidevineYouTubePerformanceTests testL3Cenc720P30 pass com google android per
  • ZYNQ 在linux 通过AXI_GPIO操作电平

    在petalinux 通过AXI GPIO操作电平 以zynq为例 xff0c vivado工程 xff1a axi gpio n都是选择的一位输出 xff1a 管脚约束 xff1a set property SEVERITY Warnin
  • FSK,PSK,ASK,BPSK调制

    信号调制常用的三种基本方法是 xff1a 调幅 调频和调相 1 振幅调变 xff0c 简称为调zhi幅 xff0c 通过改变输出dao信号的振幅 xff0c 来实现传送信息的目的 一般在调制端输出的高频信号的幅度变化与原始信号成一定的函数关
  • ZYNQ移植vxworks系统

    版本 xff1a ZYNQ7010 xff0c VxWorks 6 9 ZYNQ PL端有灵活性好 xff0c 资源丰富 xff0c 可反复编程速度快的优势 xff0c 通过 PS的外设并行 AXI总线外挂 PL接口 xff0c 使用 FP
  • OpenCV-Python 3.X: cv2.xfeatures2d 无法使用问题解决

    由于专利的问题surf和sift特征已经被移到xfeatures2d里面 xff0c 这个模块需要安装opencv contrib python opencv的dnn模块可以加载深度学习模型 xff0c 但是dnn需要3 4以上 xff0c
  • 旧款Mac开启随航(sideCar)功能

    看到这个标题 不得不吐槽苹果 命名软硬件都可以支持 但是故意让旧设备不支持这个功能 真是鸡贼 吐槽完毕 本文参考博客 http dev zeppel eu luca SidecarCorePatch 里面是英文版的 所以我总结翻译以下几点
  • Masonry框架源码分析

    相信大多数iOS开发者对Masonry框架并不陌生 本文是笔者通读Masonry的代码之后的一篇总结 也希望可以帮助大家更好的理解该框架 怎奈笔者才疏学浅 如有遗漏或错误也欢迎大家评论区指出 大家一起进步 iOS布局的演进 在说Masonr
  • iOS面试题总结-未完待续

    iOS面试总结 1 网络 HTTP协议 HyperText Transfer Protocol 的请求和响应 请求 请求头 请求行 请求体 请求行 指定请求方法 请求路径 协议版本等信息请求头 描述客户端环境 例如 host要请求的主机地址
  • Mac本地生成SSH Key 的方法

    1 查看秘钥是否存在 打开终端查看是否已经存在SSH密钥 xff1a cd ssh 如果没有密钥则不会有此文件夹 xff0c 有则备份删除 也可以直接删除 2 生成新的秘钥 命令如下 ssh keygen t rsa C 34 yourem
  • Charles网络抓包工具使用教程

    1 前言 xff1a Charles是一款抓包修改工具 xff0c 相比起burp xff0c charles具有界面简单直观 xff0c 易于上手 xff0c 数据请求控制容易 xff0c 修改简单 xff0c 抓取数据的开始暂停方便等等
  • 开源许可证

  • CocoaPods如何指定版本号

    一个简单的podfile pod 39 AFNetworking 39 39 gt 1 0 39 版本号可以是1 0 xff0c 可以是1 1 xff0c 1 9 xff0c 但必须小于2 一个更简单的podfile pod 39 AFNe
  • ipa包上传itunes store失败

    昨天打包上传ipa包 遇到了故障 开始以为是网络问题 但是切换了各种网络之后发现这个不是网络问题 我推测应该是苹果在mac上更新了什么东西 换用application Loader 工具上传还是不行 但是比Xcode直接上传的好处是 可以看
  • Flutter 安装 (Mac环境)

    Flutter 安装 今天偶然看到一个公众号写了一篇关于Flutter 的文章 感觉挺好 所以就来尝试一下 整个安装过程挺简单 但也不是特别顺利 因为我自己使用的是Mac系统所以这里所有操作都是Mac系统下的操作 安装Flutter SDK
  • 删除桌面上出现无文件名图标的方法

    问题现象 xff1a 桌面上出现了无文件名及后缀的图标 xff0c 当用户是管理员模式时看不到 xff0c 当用户为user权限下能看的得见 xff08 其他权限下没试 xff09 处理方法 xff1a 1 桌面上右击 属性 桌面 自定义桌
  • Hadoop之MapReduce

    摘要 xff1a MapReduce是Hadoop的又一核心模块 xff0c 从MapReduce是什么 xff0c MapReduce能做什么以及MapReduce的工作机制三方面认识MapReduce 关键词 xff1a Hadoop
  • Linux常用命令

    摘要 xff1a 采用命令行模式操控Linux系统非常重要 本文总结Linux常用的命令 xff0c 包括命令的含义 xff0c 命令的用法以及命令的拓展 关键词 xff1a 命令行模式 Linux常用命令 给Linux系统下达命令 xff
  • Hadoop之HDFS文件操作

    摘要 xff1a Hadoop之HDFS文件操作常有两种方式 xff0c 命令行方式和JavaAPI方式 本文介绍如何利用这两种方式对HDFS文件进行操作 关键词 xff1a HDFS文件 命令行 Java API HDFS是一种分布式文件

随机推荐

  • R实战读书笔记四

    第三章 图形入门 本章概要 1 创建和保存图形 2 定义符号 线 颜色和坐标轴 3 文本标注 4 掌控图形维数 5 多幅图合在一起 本章所介绍内容概括如下 一图胜千字 xff0c 人们从视觉层更易获取和理解信息 图形工作 R具有非常强大的绘
  • R语言——数据分析的一把利剑

    R语言 xff0c 我把它称之为数据分析的一把利剑 为什么这么说呢 xff1f 先让我们看一下 xff0c 什么是数据分析 xff1f 所谓数据分析 xff0c 就是以商业目的为驱动 xff0c 所开展的获取数据 处理数据 分析数据 展示数
  • 【爱上Linux】第一课 Linux概述

    学习应该是快乐的事情 快乐的东西应该要分享开来 xff0c 人人都快乐 xff01 爱上Linux 第一课 Linux概述 在本课中 xff0c 和朋友们一起来思考这些问题 问题一 xff1a 谈Linux学习 xff1f 从四个方面来看
  • Android日志框架SLF4J Android

    Android日志框架SLF4J 步骤 xff1a xff08 1 xff09 加入所需要的的jar包slf4j android 1 6 1 RC1 jar xff08 2 xff09 用法 private static final Log
  • 链表的创建与遍历

    链表 xff0c 简而言之 xff0c 就是基于链式储存结构下的线性表 链表包括单向链表 双向链表以及循环链表 链表是一种很常用的数据结构 xff0c 其定义如下 xff1a 单向链表的定义 定义说明 xff1a 包括数据域和指针域 typ
  • Java异常机制

    Java异常 xff08 Exception xff09 又称例外 xff0c 是一种运行时错误 Java异常机制就是对于Java异常的处理方法 xff0c 使用Java异常机制能提升程序的容错性 xff0c 从而使程序更加健壮与安全 ja
  • Java序列化与反序列化

    Java序列化与反序列化是什么 xff1f 为什么需要序列化与反序列化 xff1f 如何实现Java序列化与反序列化 xff1f 本文围绕这些问题进行了探讨 1 Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程
  • Java语言中几个常用的包

    Java采用包结构来组织和管理类和接口文件 本文介绍Java语言类库中几个常用的包 xff0c 因为这几个包在软件开发与应用中经常需要用到 xff0c 其中有些包是必要的 若是离开它 xff0c 还真不能做事情了 第一个包 xff1a ja
  • Android的系统架构

    Android的系统架构采用了分层架构的思想 xff0c 如图1所示 从上层到底层共包括四层 xff0c 分别是应用程序程序层 应用框架层 系统库和Android运行时和Linux内核 图1 xff1a Android系统架构图 每层功能简
  • Java中 判断String 是否为空的几种方法(null 、== 、equals)

    一 基本知识 String str1 61 null str1引用为空 xff0c 它没有地址 xff0c 它是一个没有被实例化的对象 String str2 61 34 34 str2引用为空字符串 xff0c 它有地址 xff0c 它是
  • C_INCLUDES must be under the source or output directories:

    https blog csdn net cigogo article details 94546032 参考了上面大神的链接 xff0c 发现设置了绝对路径 xff0c 改为相对路径后 xff0c 正常 编译报错 xff1a LOCAL P
  • Failed to connect to raw.githubusercontent.com port 443

    Mac 安装 homebrew xff1a 1 usr bin ruby e 34 curl fsSL https raw githubusercontent com Homebrew install master install 34 报
  • NFS配置及使用

    什么是NFS NFS Network File System 即网络文件系统 xff0c 是FreeBSD支持的文件系统中的一种 xff0c 它允许网络中的计算机之间通过TCP IP网络共享存储 在NFS的应用中 xff0c 本地NFS的客
  • 在idea中配置maven(阿里云镜像)

    1 下载maven 要使用maven当然要去下载 xff0c 可以去官网下载 xff0c 去官网下载需要自己配置 xff0c 这里可以使用我配置好的maven xff1b 链接 xff1a https pan baidu com s 1Zn
  • MTK6582资料帖和问题帖集合

    MTK6582资料帖汇总 Driver All in One V1 0 MT6572 MT6582 AOSP 发给需要的 MT6582memorydevicelist MT6582完整版DATASHEET xff0c xff1e 50M x
  • MYSQL笔记1

    MYSQL笔记 参照 MySQL数据库原理 设计与应用 清华大学出版社 第二章 数据库基本操作 2 1数据库操作 2 1 1创建数据库 create database if not exists xxx 2 1 2查看数据库 1 查看存在的
  • JetBrains学生认证

    1 首先找到JetBrains官网 JetBrains官网链接 2 找到学生申请页面 学生申请页面链接 3 选择申请方式 xff1a 官方文件 选择方式一共有四种 xff0c 较简单的是其中两种 xff0c 分别是大学电子邮箱地址和官方文件
  • Ubuntun18.04下载微信

    1 下载Wine环境包 xff1a http archive ubuntukylin com software pool partner ukylin wine 70 6 3 25 amd64 deb 2 下载微信 xff08 wine x
  • Java8使用Stream流实现List列表的查询、统计、排序、分组

    Java8提供了Stream xff08 流 xff09 处理集合的关键抽象概念 xff0c 它可以对集合进行操作 xff0c 可以执行非常复杂的查找 过滤和映射数据等操作 Stream API 借助于同样新出现的Lambda表达式 xff
  • MySQL的COUNT语句,竟然都能被面试官虐的这么惨!?

    关于数据库中行数统计 xff0c 无论是MySQL还是Oracle xff0c 都有一个函数可以使用 xff0c 那就是COUNT 但是 xff0c 就是这个常用的COUNT函数 xff0c 却暗藏着很多玄机 xff0c 尤其是在面试的时候