返回顶部
首页 > 资讯 > 数据库 >浅谈MySQL 统计行数的 count
  • 917
分享到

浅谈MySQL 统计行数的 count

MySQLcountMySQL统计行数 2022-05-31 04:05:07 917人浏览 八月长安
摘要

Mysql count() 函数我们并不陌生,用来统计每张表的行数。但如果你的表越来越大,且是 InnoDB 引擎的话,会发现计算的速度会越来越慢。在这篇文章里,会先介绍 count() 实现的原理及原因,然后是 c

Mysql count() 函数我们并不陌生,用来统计每张表的行数。但如果你的表越来越大,且是 InnoDB 引擎的话,会发现计算的速度会越来越慢。在这篇文章里,会先介绍 count() 实现的原理及原因,然后是 count 不同用法的性能分析,最后给出需要频繁改变并需要统计表行数的解决方案。

Count() 的实现

InnoDB 和 MyISAM 是 mysql 常用的数据引擎,由于两者实现的不同,导致 count() 操作计算的效率也不同。

对于 MyISAM 来说,它把每个表的总行数都存在了磁盘上,因此使用 count(*) 计算时,效率很高直接返回结果。但如果加入了 where 条件,依然会进行搜索,所以效率是不高的。

对于 InnoDB 来说,在进行 count(*) 运算时,会把数据从引擎中一行行读出来,然后累计计数,自然表大了之后,效率就变低了。

那么,为什么 InnoDB 不能像 MyISAM 在表中记录呢?原因就在于 InnoDB 比 MyISAM 多了支持事务的特性,同时也需要一定的取舍。由于 mvcC 的控制,使得 Mysql 具有并发的能力,也就是说对于同一时刻,InnoDB 返回的表的行数是不一定的,事务看到的行数与开启后的一致性视图有关,换句话说,每个事务能看到的数据版本是不一样的,只能一行行拿出来进行判断。

像下面的事务,假设表 t 有 10000 条数据:

Session A Session B Session C
select count(*) from t;
insert into t ();
begin;
insert into t();
select count(*) from t; select count(*) from t; select count(*) from t;
10000; 结果是 10002 结果是 10001

对于 Session A 来说,Session B 未提交不可见,Session C 提交了,但是在 Session A 启动后提交的,也不可见。所以是 10000.

而对于 Session B 而言,Session C 在启动之前提交,自己又插入了一条,所以结果是 10002.

其实 InnoDB 在进行 count(*) 操作时,还是做了优化的,在进行 count(*) 操作时,由于普通索引会保存主键的 id 值,所以会找到最小的那颗普通索引树进行查找,而不是去遍历主键索引树。

在保证逻辑正确的前提下,减少扫描的数据量,是数据库系统设计的通用法则。

另外在使用 show table status 时,也可以查询出行数,而且速度很快,但需要注意的是,该命令是通过索引统计的值来采样估算的。官方文档说误差可以有 40%-50%.

但如果我们真的需要实时的获取的某个表的行数,应该怎么办呢?

手动保存表的数量

用缓存系统来保存计数

对于进行更新的表,可能会想到用缓存系统来支持。比如 Redis 里来保存某个表总行数。

每次插入数据库时,Redis 计数加一,相反则减一,这样看起来读写操作都很快,但会存在一些问题。

缓存系统会丢失更新:

对于 Redis 在内存中的数据,需要定期的同步到磁盘中,但对于 Redis 异常重启,就没有办法了。比如在 Redis 中插入后,Redis 重启,数据没有持久化到硬盘。这时可以在重启 Redis 后,从数据库执行下 count(*) 操作,然后更新到 Redis 中。一次全表扫描还是可行的。

逻辑不精确:

假设一个页面中,需要显示一张表的行数,以及每一条数据。在实现时,可以先从 Redis 取数量,然后从数据库里取记录。

但可能会出现这样的情况:

  1. 数据库查到 100 行结果里有最新插入的记录,而 Redis 计数里少 1.
  2. 数据库查到 100 行结果没有最新的记录,但 Redis 计数却多了 1.
Session A Session B
插入一条数据; T1
读 Redis 计数; T2
从数据库中查记录;
Redis 计数加 1; T3

对于 Session B 来说,在 T2 时刻,会发现 Redis 的数量比数据库少 1 条。

Session A Session B
Redis 计数加 1; T1
读 Redis 计数; T2
从数据库中查记录;
插入一条数据; T3

对于 Session B 来说,在 T2 时刻,会发现 Redis 的数量比数据库多 1 条。

其实产生问题的原因就是因为 Redis 和数据库查记录没有在同一个事务中。

用数据库保存

由于 InnoDB 引擎的支持,MySQL 本身是支持事务的,所以将 Redis 的插入操作换成在数据库的更新操作,就可以利用在RR级别下的事务特性,进而保证数据的精确性。

而且还有一点,由于 redo log 的支持,在 MySQL 发生异常时,是可以保证 crash-safe。

不同 count 用法的执行效率

count() 本身是一个聚合函数,对于返回的结果集,一行行地判断。如果参数不是 NULL 的话,会一直累加,最后返回结果。

所以 count(*), count(id), count(1) 表示都是返回满足条件的结果集总行数。

而 count(字段),则表示满足条件的数据行里,不为 NULL 的字段。

对于 count(id) 来说,InnoDB 会遍历整张表,把每行 id 取出来,给 server 层。Server 判断 id 是否为空,然后累加。

对于 count(1) 来说,InnoDB 会遍历整张表,但不取值。Server 层会自己放入 1,然后累加。

所以对于 count(1) 的执行会比 count(*) 要快,少了解析数据行以及拷贝字段值的操作。

对于 count(字段) 来说,如果字段定义时是 not null, 会一行行读出,并判断不能为 null,然后累加。如果定义时可以为 null,执行时,需要将值去除,判断不是 null 才累加。

count(*) 除外,专门做了优化,不取值,直接按行累加,并且会找到最小的索引树进行计算。

总结

MySQL count() 函数的执行效率和底层的数据引擎有关。MyISAM 不加 where 条件,查询会很快,但不支持事务。InnoDB 支持事务,由于 MVCC 的实现,导致每次查询都需要一行行的扫描,效率不高。

解决方法可以通过设计外部缓存如 Redis,保存记录。但存在异常重启和数据不准确的情况。可以通过在 InnoDB 中新建一张表,保存记录这样的解决方案。

最后,InnoDB 对 count(*) 做了独立的优化,而其他的 count 操作,则需要额外的操作。

以上就是浅谈MySQL 统计行数的 count的详细内容,更多关于Mysql count的资料请关注自学编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: 浅谈MySQL 统计行数的 count

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

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

猜你喜欢
  • 浅谈MySQL 统计行数的 count
    MySQL count() 函数我们并不陌生,用来统计每张表的行数。但如果你的表越来越大,且是 InnoDB 引擎的话,会发现计算的速度会越来越慢。在这篇文章里,会先介绍 count() 实现的原理及原因,然后是 c...
    99+
    2022-05-31
    MySQL count MySQL 统计行数
  • MySQL统计函数count详解
    MySQL统计函数count详解 1. count()概述2. count(1)和count(*)和count(列名)的区别3. count(*)的实现方式 1. count()概述 count() 是一个聚合函数,返回指定匹配...
    99+
    2023-08-17
    mysql 数据库 统计函数count
  • MySQL count(*)统计总数问题汇总
    目录1. MyISAM存储引擎计数为什么这么快?2. 能不能手动实现统计总行数3. InnoDB引擎能否实现快速计数在日常开发工作中,我经常会遇到需要统计总数的场景,比如:统计订单总数、统计用户总数等。一般我们会使用my...
    99+
    2024-04-02
  • MySQL count(*)统计总数问题汇总
    目录1. MyISAM存储引擎计数为什么这么快?2. 能不能手动实现统计总行数3. InnoDB引擎能否实现快速计数在日常开发工作中,我经常会遇到需要统计总数的场景,比如:统计订单总...
    99+
    2024-04-02
  • 浅谈MySQL函数
    目录1、数学函数2、字符串函数3、日期函数4、加密函数 主要MySQL函数介绍又以下: 数学函数 字符串函数 时间函数 加密函数 ...
    99+
    2024-04-02
  • 浅析MySQL的基数统计
    一、基数是啥? Cardinality指的就是MySQL表中某一列的不同值的数量。 如果这一类是唯一索引,那基数 = 行数。 如果这一列是sex,枚举类型只有男女,那它是基数就是2 Cardinality越高,列就越...
    99+
    2022-05-26
    MySQL 统计 MySQL 基数统计
  • MySql统计函数COUNT的具体使用详解
    目录1. COUNT()函数概述2. COUNT()参数说明3. COUNT()判断存在4. COUNT()阿里开发规范1. COUNT()函数概述 COUNT() 是一个聚合函数,返回指定匹配条件的行数。开发中常用来统...
    99+
    2022-08-14
    MySql统计函数COUNT MySqlCOUNT
  • MySQL-带条件计数COUNT
    首先我们要知道MySQL怎么能统计出记录有多少条,那必然是我们的count()函数。 count又可以分为,count(*),count(字段),count(常量) count(*) 统计所有行数co...
    99+
    2023-10-24
    mysql sql 数据库
  • Mysql count 带条件计数
    count 带条件计数 mysql 统计条数很简单, 使用 count 函数就行,但是带条件统计,可能有些小伙伴跟我一样,还有些疑问,废话不多说 上代码 表中三条数据 1. count(*) 和 count(字段) : 区别:count(*...
    99+
    2023-08-19
    mysql 数据库 java
  • nginx中一个请求的count计数跟踪浅析
    首先说明一下应用方式,有两个nginx的模块,一个名为jtxy,另一个名为jtcmd。一个http请求来了,会进入jtxy的模块处理,jtxy会创建出一个子请求发送给jtcmd,jt...
    99+
    2024-04-02
  • Mysql中使用count加条件统计
      Mysql中count()函数的一般用法是统计字段非空的记录数,所以可以利用这个特点来进行条件统计,注意这里如果字段是NULL就不会统计,但是false是会被统计到的,记住这一点,我们接下来看看几种常见...
    99+
    2024-04-02
  • 浅谈数据库--事务(mysql)
    事务  事务其实是一组对数据库增删改操作的组合,可以这样来理解,当你往某个人身上打1000元的时候,在数据库中会发生两个改变,一个是你的钱减少了,另一个是那个人的钱增加了,这两个操作必须同时满足,...
    99+
    2024-04-02
  • 【①MySQL】浅谈数据库系统:MySQL的简介与安装配置
    前言 欢迎来到小K的MySQL专栏,本节将为大家带来MySQL的简介与安装配置的详细讲解~ 目录 前言一、数据库系统概述数据(Data)数据库(Database)数据库管理系统(Data...
    99+
    2023-09-17
    数据库 mysql java
  • 浅谈numpy 中dot()函数的计算方式
    如下所示: a = np.arange(1, 5).reshape(2, 2) b = np.arange(2, 6).reshape(2, 2) c = a * b dot =...
    99+
    2024-04-02
  • 浅谈C++有理数的表达和计算
    #ifndef Rational_hpp #define Rational_hpp #include <stdio.h> #include <string>...
    99+
    2024-04-02
  • 浅谈MySQL中的group by
    目录1、前言 2、准备user表2.1 group by规则2.2 group by使用2.3 having使用2.4 order by与limit2.5 with rol...
    99+
    2024-04-02
  • 浅谈mysql执行过程以及顺序
    目录一:mysql执行过程1.1:连接器1.2:缓存1.3:分析器1.4:优化器1.5:执行器二:执行的状态三:sql的执行顺序3.1:from3.2:join on3.3:wher...
    99+
    2024-04-02
  • 3NF浅谈BI领域的数据模型设计
    目录: 第一部分:基础概念 第二部分:设计方式 第三部分:银行业数据模型基本概念介绍 第四部分:银行业数据模型分主题介绍 第五部分:ODS和EDW 第一部分:基础概念 ...
    99+
    2024-04-02
  • 浅谈mysql 树形结构表设计与优化
    前言 在诸多的管理类,办公类等系统中,树形结构展示随处可见,以“部门”或"机构"来说,接触过的同学应该都知道,最终展示到页面的效果就是层级结构的那种,下图随机列举了一个部门的树型结构...
    99+
    2024-04-02
  • sql中count统计个数怎么实现
    在 SQL 中,可以使用 COUNT 函数来统计数据表中满足特定条件的记录数量。COUNT 函数的语法如下: SELECT ...
    99+
    2024-03-11
    sql
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作