当前位置: 首页 > news >正文

面试:MySQL 数据库中的 count(1)、count(*)、count(字段)有什么区别?

目录

1.背景

2.常见的面试回答

3.有经验的面试回答

4.总结&评论

完美!


1.背景

出去找工作,或者在开发的时候,或者初学的时候,可能会遇到count(1)和count(*)有什么区别呢?那个效率更高呢?

2.常见的面试回答

在 MySQL 数据库中,COUNT() 函数是一个聚合函数,用于计算表中的行数或者满足特定条件的行数。COUNT() 函数可以有不同的参数,主要包括 COUNT(1)COUNT(*) 和 COUNT(字段),它们之间在功能和使用上有所区别,但主要区别在于性能和语义上的一些细微差别。

  1. COUNT(*)

    • COUNT(*) 会计算包括 NULL 值在内的所有行数。这是因为它不依赖于任何列的值,而是直接计算表中的行数。
    • 在大多数情况下,COUNT(*) 是性能最优的选择,因为数据库优化器能够利用索引或者其他统计信息来快速计算出表中的行数,特别是在不需要过滤数据(即没有 WHERE 子句)时。
    • COUNT(*) 的语义非常清晰,表示“计算所有行”。
  2. COUNT(1)

    • COUNT(1) 在逻辑上等同于 COUNT(*),因为它并不真正依赖于表达式 1 的值。数据库引擎在处理 COUNT(1) 时,也是计算所有行数,包括包含 NULL 值的行。
    • 尽管 COUNT(1) 和 COUNT(*) 在逻辑上等价,但在某些数据库系统(包括 MySQL)中,COUNT(*) 可能因为优化器的特殊优化而具有更好的性能。
    • 使用 COUNT(1) 的主要原因可能是出于习惯或者是在其他数据库系统中,COUNT(1) 可能具有特定的优化。但在 MySQL 中,推荐使用 COUNT(*)
  3. COUNT(字段)

    • COUNT(字段) 会计算指定字段中非 NULL 值的数量。如果字段中包含 NULL 值,那么这些 NULL 值不会被计入总数。
    • 当你需要计算某个特定字段的非空值数量时,应该使用 COUNT(字段)
    • 相比于 COUNT(*) 和 COUNT(1)COUNT(字段) 的性能可能会稍差,特别是当该字段未被索引且表中包含大量数据时,因为数据库需要扫描整个表来统计非 NULL 值。

总结:

  • 在大多数情况下,如果你只是需要计算表中的行数,推荐使用 COUNT(*),因为它具有最好的性能和最清晰的语义。
  • COUNT(1) 和 COUNT(*) 在 MySQL 中性能上几乎没有区别,但推荐使用 COUNT(*)
  • 当你需要计算某个字段中非 NULL 值的数量时,使用 COUNT(字段)

3.有经验的面试回答

面试回答思路:
面试本质:不是点对点回答问题,而是面试官通过提出一个话题(问题),获取到面试者的思维和技术水平;
1.回答基本定义
2.说说实际生产中的运用
3.引导到自己擅长的技术点上深入探讨

count函数的语义

count() 是一个聚合函数,函数的参数不仅可以是字段名,也可以是其他任意表达式,该函数作用是统计符合查询条件的记录中,函数指定的参数不为 NULL 的记录有多少个

在通过 count 函数统计有多少个记录时,MySQL 的 server 层会维护一个名叫 count 的变量。

server 层会循环向 InnoDB 读取一条记录,如果 count 函数指定的参数不为 NULL,那么就会将变量 count 加 1,直到符合查询的全部记录被读完,就退出循环。最后将 count 变量的值发送给客户端。

实际生产中的应用
在实际生产中我们最常见的应用场景是做分页的时候会用到count(*),
当然也不是自己写sql写的count(*),一般是分页插件自动生成的sql语句查询总条数,如果观察一下日志输出就会发现使用的是count(*),
因此个人觉得count(*)应该是COUNT(*)和COUNT(1)和COUNT(字段)中效率想对来说较好的;

技术探讨

另外结合mysql的数据库的特性(逻辑架构和sql的执行流程)
count(*)和count(1) 估计效率应该差不多吧!
因为sql在执行的时候会经过这几个流程(链接->查询缓存->解析sql->优化sql->执行sql->返回结果),
这样来思考的话,那么count(*)和count(1)很有可能会被优化器优化成一样;

再来说一下count(字段),说到字段,就要分析3中情况
1.不是索引的情况
2.count(二级索引)是索引,但不是主键的情况
3.count(id)是主键


不是索引的话效率一定会很低,需要扫描整个数据库表,效率低于count(*)和count(1)


count(id)通常是主键索引,在 InnoDB 中,主键索引是聚簇索引,它存储了实际的数据行。执行 count 时,InnoDB 需要遍历整个聚簇索引来统计行数。

count(二级索引)是指存储了索引列和主键列的指针,而不包含实际的数据行。因此,二级索引相对来说更小。执行 count 时,InnoDB 只需要遍历这个较小的二级索引,而不是整个聚簇索引,需要读取的数据页更少,所以成本更低。

当然,理论归理论,具体情况具体分析,具体的性能差异取决于索引的大小和表的结构,可以用 explain 语句查看查询计划和成本。

实际生产用法

最后,  如果表的数据量过大,比如千万级别,一般来说都不会在频繁使用count来统计总条数,无论用那种count的方式都会很慢


常见的做法是
1.比如在分页的时候,不会显示总条数,查询数据需要传入最小id,这也是有弊端的比如不能从第二页转到第五页等;比如之前我们在做拉取某东的产品的时候,就会发现拉取产品需要传入上次处理的最后的产品id;


2.弄一个中间表存储表的总行数等;

总之,当数据量大的时候不仅仅是需要技术侧努力优化,还需要结合业务,看看如何做更合理,更高效,性价比更高!

4.总结&评论

从上面的2种回答中,

你会发现第一种是典型的点对点的回答方式,也是大多数面试者回答的方式,就像我们读书的时候做考试卷子一样的回答;

第二种回答,更偏向口头沟通,更在乎思维,层层递进,每得出一个结论都给出了是如何思考的,并且给出了实际生产中的做法和将会遇到的问题;

如果你面试官,你会觉得那个更容易面上呢?

在评论区给出你个观点吧!

完美!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • ssh免密认证配置
  • 解决vue 初始化页面闪动问题
  • c++STL容器中vector的使用,模拟实现及迭代器使用注意事项和迭代器失效问题
  • HTB Driver红队笔记靶机精讲笔记
  • c++中的Stack与Queue
  • 相似度计算方法
  • 前端日历插件VCalendar
  • 实验2-4-7 求平方与倒数序列的部分和
  • 【iOS】iOS内存五大分区
  • pip安装mysqlclient报错
  • The First项目报告:解读Trading Bot黑马,交易狙击手Banana Gun
  • RAG 革命:NVIDIA 工作站如何成为企业 AI 的秘密武器
  • 模型优化—动量梯度下降
  • vmware上,虚机经常丢失网卡。导致无法上网。
  • 【初阶数据结构篇】冒泡排序和快速排序(中篇)
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • EOS是什么
  • HTTP请求重发
  • If…else
  • JAVA_NIO系列——Channel和Buffer详解
  • Python利用正则抓取网页内容保存到本地
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • Web Storage相关
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 记一次和乔布斯合作最难忘的经历
  • 蓝海存储开关机注意事项总结
  • 算法---两个栈实现一个队列
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 微信小程序--------语音识别(前端自己也能玩)
  • 国内开源镜像站点
  • ​字​节​一​面​
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • #define
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • $ git push -u origin master 推送到远程库出错
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (一)WLAN定义和基本架构转
  • (正则)提取页面里的img标签
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .net core 6 集成和使用 mongodb
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .NET 反射 Reflect
  • .NET8 动态添加定时任务(CRON Expression, Whatever)
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • @font-face 用字体画图标
  • [bzoj1006]: [HNOI2008]神奇的国度(最大势算法)
  • [C++][ProtoBuf][初识ProtoBuf]详细讲解