首页 > 数据库 >搞定面试官 - 可以介绍一下在 MySQL 中你平时是怎么使用 COUNT() 的嘛?

搞定面试官 - 可以介绍一下在 MySQL 中你平时是怎么使用 COUNT() 的嘛?

时间:2022-08-15 00:16:24浏览次数:76  
标签:COUNT count 面试官 index InnoDB MySQL Null id

大家好,我是程序员啊粥。

相信在大家的工作中,有很多的功能都需要用到 count(*) 来统计表中的数据行数。同时,对于一些大数据的表,用 count 都是瑟瑟发抖,往往会结合缓存等进行处理。

那么,我们今天就来分析一下,在 InnoDB 中,关于 count 的一些处理措施和优化。

常见的 count 使用方式有三种

  • count(*)
  • count(主键 Id)/count(某个字段)
  • count(1)

首先 count(*)、count(主键 Id)/count(某个字段) 和 count(1) 都表示返回满足条件的结果集的总行数。

他们的差异在于:count(字段)表示返回满足条件的数据行里面,参数“字段”不为 NULL 的总条数,而 count(1) 会统计表中的所有的记录数,包含字段为 NULL 的记录,但它是用 1 代替了所有列,不在关注表中具体列的情况,count(*) 包括了所有的列,相当于行数,在统计结果的时候,它同样不会忽略为 NULL 的值。

接下来,我们就一个个地来看看。

对于 count(主键 id) 来说,InnoDB 引擎会遍历整张表,把每一行的 id 值都取出来,返回给 server 层。server 层拿到 id 后,判断是不可能为空的,就按行累加。

对于 count(1) 来说,InnoDB 引擎遍历整张表,但不取值。server 层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加。

单看这两个用法的差别的话,相信你能对比出来,count(1) 执行得要比 count(主键 id) 快。因为从引擎返回 id 会涉及到解析数据行,以及拷贝字段值的操作,少一步操作就能少一些时间。

同时对于 count(字段) 来说:如果这个“字段”是定义为 Not Null 的话,一行行地从记录里面读出这个字段,判断发现这个字段不能为 Null,那么直接按行累加;但是如果这个“字段”定义允许为 Null 的话,那么执行的时候,还要把具体的字段值取出来再判断一下,不是 Null 才能进行累加。

但是 count(*) 是例外,MySQL 专门对其做出了优化,MySQL 每发布一个新版本,都会放出相应的 Release Notes,我们注意到 5.7.2 版本的发布说明中提到:

InnoDB: SELECT COUNT() FROM t statements now invoke a single handler call to the storage engine to scan the clustered index and return the row count to the Optimizer. Previously, a row count was typically performed by traversing a smaller secondary index and invoking a handler call for each record. A single handler call to the storage engine to count rows in the clustered index generally improves SELECT COUNT() FROM t performance. However, in the case of a large clustered index and a significantly smaller secondary index, performance degradation is possible compared to performance using the previous, non-optimized implementation. For more information, see Limits on InnoDB Tables.

简单地说就是:COUNT(*)会选择聚集索引,进行一次内部 handler 函数调用,即可快速获得该表行数

所以,它也不存在需要取值判断是否为 Null 的计算操作,可以说效率有很大的提高。

所以结论是:按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(),所以我建议你,尽量使用 count()。

而不是受我们惯性思维的影响,觉得 count(*) 可能和 select() 一样,效率会很低,反之,这是效率最高的。

当然,你如果实际中遇到了大数据量的表,可能把具体的行数缓存下来,或者专门建立一张表来存储这个 count() 值,而不是每次都去表里扫描一次。

好了,今天的内容到此就结束了,关于 count() 的用法,你用对了嘛?

评论区留言我们一起讨论哇!

我是程序员啊粥,关注我,我们一起在技术海洋中向上生长。

标签:COUNT,count,面试官,index,InnoDB,MySQL,Null,id
From: https://www.cnblogs.com/zhoudl/p/16586783.html

相关文章

  • MySQL使用Explain查看执行计划
    概述Explain模拟优化器执行SQL语句,在5.6以及以后的版本中,除了select,其他insert,update和delete均可以使用explain查看执行计划,从而知道mysql是如何处理sql语句,分析查询语句......
  • MySQL IF CASE
    IF函数语法如果expr1是TRUE,则IF()的返回值为expr2;否则返回值则为expr3。IF(expr1,expr2,expr3)样例--简单SELECTIF(t.gender=0,'男','女')SEXFROM......
  • MySQL事务执行一半,连接被kill掉会怎样?
     官方文档解释: https://dev.mysql.com/doc/refman/8.0/en/kill.html优秀博客:https://cloud.tencent.com/developer/article/1815896         ......
  • MySQL基础
    今日内容数据存取演变史一、文本文件  文件路径不一致:C:\a.txtD:\aaa\b.txtE:\ccc.txt  数据格式不一致:jason|123tony$123kevin@123二、软件开发目录规范......
  • 周回顾并发编程与数据库08.14:UDP协议、操作系统发展史、相关名词、进程、线程、验证py
    目录UDP协议操作系统发展史相关名词进程线程锁信号量event事件池协程数据库MySQLSQL与NoSQL内容UDP协议Internet协议集支持一个无连接的传输协议,该协议......
  • 【2022.8.12】MySQL数据库(1)
    今日内容概要主体:数据库(入门核心)数据存取演变史数据库软件应用史数据库的本质数据库的分类MySQL数据库基本使用系统服务制作基本SQL语句今日内容详细数......
  • mysql 服务无法启动是什么原因?
    1、将目录中配置文件my.default.ini改名为my.ini移至bin目录下。2、启动命令行,将目录切换到mysql安装目录的bin目录下。3、在命令行执行命令:mysqld--initialize--user=......
  • 浅谈MySQL的sql_mode
    SQLmode今天我们来分享一下MySQL的SQLmode,这也是我们比较容易忽略的一点,我们在一开始安装数据库的时候其实就要先考虑要保留哪些SQLmode,去除哪些,合理的配置能够减少......
  • VS2010 + Mysql5.7 使用ADO.Net Entity Framework
        系统很LOW,不想花太多时间来升级,可想做点什么,总是这也不行那也不行,更种安装要不就是vs版本太低,要不不支持低版本的mysql,调试起来很费时。用老版办法写代码又太费......
  • 搞定面试官 - 你可以介绍一下在 MySQL 中,哪些情况下 索引会失效嘛?
    大家好,我是程序员啊粥,前边给大家分享了*MySQLInnoDB索引模型在MySQLInnoDB中,为什么delete删除数据之后表数据文件大小没有变如何计算一个索引的长度如何查看......