首页 > 其他分享 >count(?)为什么越来越慢?

count(?)为什么越来越慢?

时间:2024-04-12 14:33:23浏览次数:25  
标签:count 为什么 返回 一行 索引 InnoDB 越来越 主键

在日常的业务开发中,汇总记录使用select count(*) from t是常见用法,分页查询的时候都会用到,那么随着系统记录的数量越来越多,你有没有发现这条语句执行的也越来越慢了呢?

一、count(*)原理

在不同的存储引擎中,count(*)有不同的实现方式

  • MyISAM 存储引擎中,把一个表的总行数存在了磁盘上,因此执行 count(*)的时候,直接读取这个值就行了,效率很高
  • 而 InnoDB 执行 count(*)的时候,需要把一行一行数据从存储引擎里读取出来,然后累计计数

当然我们讨论的是没有带 where 语句的,如果带了 where 语句,MyISAM 返回的也不会这么快的

那么问题来了,为什么 InnoDB 不能想 MyISAM 一样,把总数存储起来,而要一行一行的读呢?

原因就是InnoDB是支持事务的,由于多版本并发控制(MVCC)的原因,InnoDB在不同时刻调用count(*)的数据是不确定的

这里举个例子,假设 T 表中有 10000 条数据,设计三个会话:

sessionA sessionB sessionB
select count(*) from t; (返回 10000)
insert into t (插入一行)
insert into t(插入一行)
select count(*) from t;(返回 10000) select count(*) from t;(返回 10002) select count(*) from t;(返回 10001)

可以看出不同时期的 count()返回的值是不一样的,每一行记录都要判断自己是否对这个会话可见,因此对 count()来说,InnoDB 只有把每一行都读出来做判断,可见性行的才能用于计算总行数

那么 InooDB 是怎么统计记录的呢?

InnoDB 是索引组织表,主键索引树的叶子节点存放的是数据,而普通索引的叶子节点存放的是主键值。所以这就导致了普通索引是比主键索引小很多的,对于 count(*)来说,遍历哪一个索引树在结果逻辑上都是一样的,因此MySQL优化器会找到最小的那一颗索引树来遍历,在保证逻辑结果正确的前提下,尽量减少扫描的数据量,是数据库系统设计的通用法则之一

二、几种 count(x)的区别

当然肯定有同学见过count(*),count(1),count(主键)count(字段)这几种用法,那么这几种 count 都有什么区别呢?

首先 count()是一个聚合函数,对于返回的结果集,一行一行的判断,如果 count 函数的参数不是 null,累计值就+1,否则不加,最终返回累计值

  • count(1):InnoDB 会扫描遍历整张表,但不取值。server 层对于返回的每一行,判断不为NULL的,进行+1累计
  • count(主键):InnoDB 会扫描遍历整张表,把每一行的 ID 都取出来,返回给 server 层,server 拿到 ID 后判断是否为 NULL,然后按行累计

但从两个用法的差距来看,count(1)会比count(主键)快一点,因为 count(主键)从引擎返回 id 会设计到解析数据行,以及拷贝字段值的操作

  • count(字段):InnoDB 一行行从记录中读取出这个字段,判断是否为NULL,不为NULL才累加
  • count(*): count(*)是例外,并不会把所有字段取出来,而是专门做了优化,不取值,count(*)肯定不为 NULL,按行累加

所以总结来说:count(*) ≈ count(1) > count(主键) > count(字段)


我是一零贰肆,一个关注Java技术和记录生活的博主。

欢迎扫码关注“一零贰肆”的公众号,一起学习,共同进步,多看路,少踩坑。

标签:count,为什么,返回,一行,索引,InnoDB,越来越,主键
From: https://www.cnblogs.com/sun2020/p/18131148

相关文章

  • 美团二面:为什么不推荐使用 MyBatis 二级缓存?大部分人都答不上来!
    为了增加查询的性能,MyBatis提供了二级缓存架构,分为一级缓存和二级缓存。这两级缓存最大的区别就是:一级缓存是会话级别的,只要出了这个SqlSession,缓存就没用了。而二级缓存可以跨会话,多个会话可以使用相同的缓存!一级缓存使用简单,默认就开启。二级缓存需要手动开启,相对复杂,而且要......
  • 工业辅助制造:冲压/压铸模具设计为什么需要仿真建模
    相关:https://isite.baidu.com/site/wjzz90of/4c6cf443-336f-4dcb-9830-1db415cee29d?fid=nHnvnWb3rHn4nH6drHn1nHfYnjuxnWcdg1D&ch=4&bd_vid=8058739110555694506&bd_bxst=EiaKu83a0D3TFeL900DD0c3dNfKOg40h000000ew8IUqcQ5-YUb6VtQN4Mp6ZaD000002bf4nb7KnbcYf1n4......
  • 为什么要使用工业仿真软件? —— CAE(Computer Aided Engineering)工程设计中的计算机
    CAE技术:引自:https://baike.baidu.com/item/CAE技术/18884456?fr=ge_ala引自:https://www.mscsoftware.com.cn/cases/173.html当前制造业市场的竞争愈演愈烈,消费者在选择产品时不仅限于一个合适的价格,而且更加注重产品的质量和品质。钣金冲压成形工艺在汽车、航空航......
  • 并发同步计数器 CountDownLatch
    概念解释CountDownLatch是Java中的一个同步辅助类,它可以让一个或多个线程等待其他线程完成操作后再继续执行。CountDownLatch内部维护了一个计数器,当计数器的值减为0时,所有等待的线程就会被唤醒。 CountDownLatch的主要方法包括:构造方法:CountDownLatch(intcount)构......
  • 为什么PCB板上需要晶振
    PCB板,即印刷电路板,是现代电子设备中不可或缺的组成部分。它的基本功能是提供电子元件之间的电气连接,使电子元件能够正确、高效地工作。然而,为了使电子设备能够正常工作,PCB板上的电子元件需要遵循一定的时序和频率要求。这就需要晶振这一重要的电子元件来提供稳定的时钟信号。......
  • 青否科技为什么要开发数字人直播源码!
    直播作为一种新的电商形态,电商直播化与直播电商化的现象已经逐渐普遍。数字人从去年双11作为集团十大黑科技正式公开亮相,该产品从以前的窗口式问答,升级为直播间的多维度互动,技术不断在进步!我们知道去年双11它最大的变化来自于一天变成了两个时段。同时,直播带货的GMV在整个电商场......
  • mos管栅极反并二极管为了加速关断,为什么不需要加速开通呢?
            MOS管栅极反并二极管的主要作用是在MOS管关断时提供一个快速放电路径给栅极电容,从而加速MOS管的关断过程。这种做法有助于减少关断时的开关损耗和电磁干扰(EMI),同时提高电路的工作效率。        为什么通常不需要加速MOS管的开通过程,主要有以下几个......
  • 为什么每个人都需要了解这些数据加密技术?
    在数字时代,数据加密技术不仅对保护企业的商业秘密至关重要,也是个人隐私安全的重要屏障。随着技术的进步和网络犯罪的增加,数据加密已经成为了信息安全领域的一个热点议题。以下是探讨为什么每个人都需要了解这些数据加密技术的几个主要原因:个人隐私保护:在我们日常的在线活动中,个......
  • Python 更新 为什么要更新 Python? 如何更新 Python? 更新 Python 可能遇到的问题——《
    Python更新为什么要更新Python?如何更新Python?更新Python可能遇到的问题——《跟老吕学Python编程》附录资料Python更新为什么要更新Python?如何更新Python?更新Python可能遇到的问题总结Python更新最近的一次Python更新中,最引人瞩目的变化之一......
  • 安防视频监控/视频集中存储EasyCVR平台开启鉴权后设备列表不展示是为什么?
    安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,EasyCVR基于云边端一体化架构,具有强大的数据接入、处理及分发能力,可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、智能AI分析接入等功......