iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >聊一聊关于MySQL的count(*)
  • 176
分享到

聊一聊关于MySQL的count(*)

聊一聊关于MySQL的count(*) 2020-12-23 00:12:09 176人浏览 绘本
摘要

2. count(*)的实现方式 据说,MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个数,效率很高。 而我们的Mysql一般都是用Innodb的引擎,Innodb是怎么实现count操作的呢

聊一聊关于MySQL的count(*)

2. count(*)的实现方式

据说,MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个数,效率很高。 而我们的Mysql一般都是用Innodb的引擎,Innodb是怎么实现count操作的呢? InnoDB 引擎就比较麻烦了,它执行 count(*) 的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。 所以,当我们的表里面的记录越来越多的时候,count(*)就会越来越慢。 当然,我们这里说的都是不带where条件的,如果带上where条件的话,MyISAM也是很慢的。

3.正确的打开方式

嗯,首先还是说,mysql上不太推荐用count(*)来做统计相关业务,尤其是表非常大的情况下。 那如果业务比较小,需要快速上马,那么,至少应该保证count(*)带上了科学的where条件,然后,这个表也已经建立了科学的索引

  • 如果count(*)带上的where条件,而且能够走覆盖索引,那还是可以偶尔走一走的。
  • 如果count(*)带上的where条件,能够走索引,但是需要回表,那么这种就会比较危险,尤其是随着表规模的扩大,终究是一颗雷。
  • 如果纯粹count(*),或者where条件没有任何索引,万万万不推荐!

那对于统计类的业务,推荐的几种做法:

  • 带自增id的,可以用最大id来近似获取
  • 自己计数
  • 其他数据分析平台进行聚合

4. 能否用表统计信息代替count(*)

有同学在日常使用过程中,问能否使用 系统表的统计信息 来代替count。 答案是不行。 这里的tableRows只是一个参考值。 这里的表统计信息,实际上是使用show table status获取的。这个值是如何得到的呢?我们需要了解下mysql的采样统计方法。为什么要采样统计呢? 因为把整张表取出来一行行统计,虽然可以得到精确的结果,但是代价太高了,所以只能选择“采样统计”(所以其实mysql自己也没有count(*)的好方法)。 采样统计的时候,InnoDB 默认会选择 N 个数据页,统计这些页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,就得到了这个索引的基数。而数据表是会持续更新的,索引统计信息也不会固定不变。 所以,当变更的数据行数超过 1/M 的时候,会自动触发重新做一次索引统计。 因此,这个采样估算得来的值,是很不准的。有多不准呢,官方文档说误差可能达到 40% 到 50%。

4.关于那些奇奇怪怪的count(?)

在看一些老代码查询的时候,我们经常会看到count(1),count(id),count(字段)等方式,那它们纠结孰优孰劣,到底有没有性能上的差异呢? 这里,我们先要弄清楚 count() 的语义。 count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是 NULL,累计值就加 1,否则不加。最后返回累计值。

  • count(主键id)InnoDB 引擎会遍历整张表,把每一行的 id 值都取出来,返回给 server 层。server 层拿到 id 后,判断是不可能为空的,就按行累加
  • count(1)InnoDB 引擎遍历整张表,但不取值。server 层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加。
  • count(字段)如果这个“字段”是定义为 not null 的话,一行行地从记录里面读出这个字段,判断不能为 null,按行累加;如果这个“字段”定义允许为 null,那么执行的时候,判断到有可能是 null,还要把值取出来再判断一下,不是 null 才累加。
  • count(*)并不会把全部字段取出来,而是专门做了优化,不取值。count(*) 肯定不是 null,按行累加。

所以结论是:按照效率排序的话,count(字段)

看到这里了,原创不易,点个赞吧,你最好看了~

知识碎片重新梳理,构建Java知识图谱:https://GitHub.com/saigu/JavaKnowledgeGraph(历史文章查阅非常方便)

扫码关注我的公众号“阿丸笔记”,第一时间获取最新更新。同时可以免费获取海量Java技术栈电子书、各个大厂面试题

阿丸笔记

您可能感兴趣的文档:

--结束END--

本文标题: 聊一聊关于MySQL的count(*)

本文链接: https://www.lsjlt.com/news/4720.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 聊一聊关于php源码中refcount的疑问
    在浏览PHP源码的时候,在众多的*.stub.php中,发现了这样的注释,@refcount 1。 通过翻看build/gen_stub.php源码,发现了在解析*.stub.php...
    99+
    2022-11-13
    php源码refcount php @refcount 1
  • 聊一聊基于webman的GraphQL实现
    本篇文章给大家带来了关于GraphQL的相关知识,其中主要跟大家聊一聊有关基于webman的GraphQL实现,感兴趣的朋友下面一起来看一下吧,希望对大家有帮助。基于PHP的GraphQL由于加载指令(directive)和解析schema...
    99+
    2023-05-14
    webman php GraphQL
  • 详细聊聊关于Mysql联合查询的那些事儿
    目录联合查询之union 1. 查询中国各省的ID以及省份名称 2. 湖南省所有地级市ID、名字 3. 用union将他们合并 联合查询之union a...
    99+
    2024-04-02
  • 详细聊聊关于sql注入的一些零散知识点
    目录零、本文涉及知识点一、sqlmap写一句马的过程(-- os-shell)1.1 简述过程1.2 一个小问题二、堆叠注入:2.1 什么是堆叠注入2.2 如何判断存在堆叠注入?2....
    99+
    2024-04-02
  • 聊聊关于python的requirements文件和虚拟环境的创建
    目录 1. requirements 的创建 1.1 创建整个环境的requirements文件 1.2 创建单个项目的 requirements 文件 2. 利用conda创建新环境 3.  安装requirements文件 4. con...
    99+
    2023-09-03
    python 开发语言 pycharm
  • 聊聊有关golang ()和.() 的转换
    Golang中的()和.()转换在Golang中,()和.()是两种非常常见的类型转换。在本篇文章中,我们将会介绍这两种类型转换的使用场景、转换规则以及相关的示例代码。()转换在Golang中,()转换是将一个非接口类型转换为一个接口类型的...
    99+
    2023-05-14
  • 聊聊PyTorch中eval和no_grad的关系
    首先这两者有着本质上区别 model.eval()是用来告知model内的各个layer采取eval模式工作。这个操作主要是应对诸如dropout和batchnorm这些在训练模式下...
    99+
    2024-04-02
  • 一文聊聊Node中的stream(流)
    流是用于在 Node.js 中处理流数据,也就是连续字节的抽象接口。 流有 4 种基本类型,本篇文章主要介绍其中两种 —— 可读流和可写流。可读的(Readable)我们可以通过 fs.createReadStream() 创建一个可读流 ...
    99+
    2023-05-14
    stream node nodejs​
  • 聊聊@RequestBody和Json之间的关系
    在使用springmvc的时候,后台@RequestBody接受的是一个json格式的字符串,一定是一个字符串。 我们可以通过@RequestBody Map @Requ...
    99+
    2024-04-02
  • 深入浅出聊一聊js中的'this'关键字
    目录前言什么是'this'关键字四种方式---1.调用函数的第一种方法是:将函数作为一种方法四种方式---2.调用函数的第二种方法是: 简单的调用函数,不将函数作为方...
    99+
    2024-04-02
  • 聊一聊Redis与MySQL双写一致性如何保证
    1 什么是一致性? 一致性就是数据保持一致,在分布式系统中,可以理解为多个节点中数据的值是一致的。 强一致性: 这种一致性级别是最符合用户直觉的,它要求系统写入什么,读出来的也会是...
    99+
    2024-04-02
  • 一文聊聊node中的path模块
    path 模块是 nodejs 中用于处理文件/目录路径的一个内置模块,可以看作是一个工具箱,提供诸多方法供我们使用,当然都是和路径处理有关的。同时在前端开发中 path 模块出现的频率也是比较高的,比如配置 webpack 的时候等。本文...
    99+
    2023-05-14
    path模块 Node.js
  • 聊一聊concurrenthashmap的size方法原理
    目录concurrenthashmap的size方法原理下面具体说一下这个size方法concurrenthashmap的size的思考我们首先会想到以下两种方法concurrent...
    99+
    2024-04-02
  • 基于flask的网页聊天室(一)
    基本目标 基于flask实现的web聊天室,具有基本的登录注册,多人发送消息,接受消息 扩展目标 除基本目标外添加当前在线人数,消息回复,markdown支持,历史消息等 创建项目 首先创建基本的文件结构: auth和chat通过蓝图...
    99+
    2023-01-31
    聊天室 网页 flask
  • 一文聊聊Node中的可读流
    本篇文章带大家解读一下Node.js流源码,深入了解下Node可读流,看看其基本原理、使用方法与工作机制,希望对大家有所帮助!1. 基本概念1.1. 流的历史演变流不是 Nodejs 特有的概念。 它们是几十年前在 Unix 操作系统中引入...
    99+
    2023-05-14
    可读流 node
  • 一文聊聊Node中的net模块
    而客户端和服务端的传输流如下如果角色变成发送者和接受者的时候,传输流如下图:可以看出来传输的过程中,从发送端开始,没经过一层协议都会加上所需要的首部信息.层层把关,层层加码. 然后到了接收端的时候, 就反而行之, 每经过一层都剥去对应的首部...
    99+
    2023-05-14
    net模块 node Node.js
  • 聊聊MultipartFile与File的一些事儿
    前言 前段时间碰到了中转文件的需求,需要使用HttpClient中转一下文件,过程为: 在实现这个需求的过程中就用得到了MultipartFile与File,而且我对前一个也不是很...
    99+
    2024-04-02
  • 带你聊聊typeScript中的extends关键字
    关于上面这张图,有几点可以单独拿出来强调一下:any 无处不在。它既是任何类型的子类型,也是任何类型的父类型,甚至可能是任意类型自己。所以,它可以赋值给任何类型;{} 充当 typeScript 类型的时候,它是有特殊含义的 - 它对应是(...
    99+
    2023-05-14
    TypeScript JavaScript
  • 一文聊聊Vue中的KeepAlive组件
    看下面的图更加直观,图片来源一篇讲keepAlive 缓存优化的文章4、如何添加到 vue devtools 组件树上sharedContext.activate = (vnode, container, anchor) => { ...
    99+
    2022-11-22
    前端 Vue.js 前端框架
  • 聊聊一些Golang的高级用法
    Go语言的出现,让我们的开发更加高效、安全、简单。代码风格简单,性能高效,它已经是许多开发者和公司的首选。然而,随着我们对Go语言的深入了解和使用,有些时候我们需要更高级、更灵活的写法来应对不同的工作需求。那么,下面就介绍一些Golang的...
    99+
    2023-05-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作