MySQL45讲之count操作

本文介绍 MyISAM 和 InnoDB 如何执行 count 操作,如果是一个需要使用 count 进行大量计数的场景,应该如何设计实现,以及不同 count 操作的效率。

MyISAM和InnoDB的count

MyISAM

MyISAM 存储引擎的每个表记录了总行数,在没有 where 条件时,直接获取该记录值返回。

InnoDB

InnoDB 获取 count 值,只能通过扫描索引树来计数。

为什么 InnoDB 只能临时扫描来计数,而不能像 MyISAM 一样存储一个总行数值?
对于同一时刻的多个查询请求,因为并发版本控制的原因,InnoDB 表应该返回多少行是不确定的,需要扫描索引,判断每行记录的可见性。

此外,InnoDB 也做了一些优化。主键索引树存储了行记录,而普通索引树只存储主键值,所以普通索引树比主键索引树小很多。因此,MySQL 会优先选择最小的索引树来遍历。 在保证逻辑正确的情况下,尽量减少扫描的数据量,是数据库系统设计的通用法则之一。

count值如何记录

1、缓存记录

比如在 Redis 中用 string 类型记录一个计数,当新增或者删除记录时,相应修改 Redis 的值。

这样是不行的,没法保证数据的一致性

首先,如果业务系统插入或删除一行数据后,系统宕机,Redis 没有写入,重启系统后 Redis 会与数据库不一致。不过,这个问题可以通过系统重启时从数据库查询一次解决。

而且,如果需要同时从 Redis 和数据库中查询数据,两者无法保证数据一致,比如从 Redis 中取出表总行数和从数据库中取出前 100 行数据。因为并发请求,只要从 Redis 和 MySQL 查询数据的操作不是原子的,数据就不是一致的。

2、数据库统计表记录

在数据库中创建一个新的统计表,以记录行数。这与前面的方法相同,并且来自并发请求的结果可能不一致。

[En]

Create a new statistical table in the database to record the number of rows. That’s the same as the previous method, and the results from concurrent requests may be inconsistent.

可以的, 行数据和统计数据同时存在数据库中,并且数据库支持事务,所以可以将多个操作封装成原子的,保证数据一致。

多种count操作的效率

count(主键id)

存储引擎遍历表拿到行记录返回,server 层解析出 id 值,判断是否为 null,统计行数。

count(1)

存储引擎遍历表不取值,server 层对于每一行放进去一个 1,判断是否为 null,统计行数。

因为 server 层需要解析引擎返回的结果拿到 id,所以 count(1) 比 count(主键id) 高效。

count(字段)

存储引擎遍历表取出字段返回,server 层解析,判断字段是否为 null,统计行数。

count(*)

MySQL 进行了优化,存储引擎遍历表不取值,server 层判断是否为 null,逐行累加。

效率从高到低:count(*) ≈ count(1) > count(主键id) > count(字段)

在刚才讨论的场景中,我们使用事务来确保准确计数。由于事务可以确保中间结果不会被其他事务读取,因此修改计数值和插入新记录的顺序不会影响逻辑结果。

[En]

In the scenario just discussed, we used transactions to ensure accurate counting. Because transactions can ensure that the intermediate results will not be read by other transactions, the order in which the count values are modified and new records are inserted does not affect the logical results.

但是,从并发系统性能的角度来看,您认为在这个事务序列中,是应该先插入操作记录,还是应该先更新盘点表?

[En]

However, from the perspective of concurrent system performance, do you think that in this transaction sequence, should the operation record be inserted first, or should the count table be updated first?

在更新操作之前执行插入操作。从并发系统性能的角度来看,应该尽可能减少锁等待,而更新操作需要锁定,直到事务提交才会释放行锁。因此,最后执行更新操作以减少锁等待,提高并发度。

[En]

Perform the insert operation before the update operation. From the perspective of concurrent system performance, lock waiting should be reduced as much as possible, while update operations need to be locked, and row locks are not released until the transaction is committed. So finally, the update operation is performed to reduce the lock waiting and improve the degree of concurrency.

Original: https://www.cnblogs.com/flowers-bloom/p/mysql45-count.html
Author: flowers-bloom
Title: MySQL45讲之count操作

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/508140/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • SQL语句大全,所有的SQL都在这里

    SQL语句大全,所有的SQL都在这里 1、说明:创建数据库 CREATE DATABASE database-name 2、说明:删除数据库 drop database dbnam…

    数据库 2023年6月9日
    066
  • Java正则表达式Pattern和Matcher类详解

    概述 Pattern类的作用在于编译正则表达式后创建一个匹配模式. Matcher类使用Pattern实例提供的模式信息对正则表达式进行匹配 Pattern类 常用方法及介绍 Pa…

    数据库 2023年6月11日
    090
  • python爬虫—xpath基础教程

    XPath: XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。XPath基于XML的树状结构,提供在数据结构树中找…

    数据库 2023年6月11日
    079
  • JUC学习笔记(四)

    JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.htmlJUC学习笔记(二)https://www.cnblogs.com/lm…

    数据库 2023年6月6日
    093
  • 数据库原理二—MySQL事务与锁

    数据库事务的四大特性 原子性A 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用 一致性C 执行事务前后,数据保持一致,多个事务对同一个数据读取…

    数据库 2023年6月6日
    065
  • Java的Lambda表达式

    函数式编程(Functional Programming)是把函数作为基本运算单元,函数可以作为变量,可以接收函数,还可以返回函数。历史上研究函数式编程的理论是Lambda演算,所…

    数据库 2023年6月9日
    087
  • zabbix的基础使用

    zabbix的基础使用 创建zabbix监控服务 环境 IP 要安装的应用 服务器 192.168.111.135 lamp架构 zabbix server zabbix agen…

    数据库 2023年6月14日
    076
  • ElasticSearch的简单api介绍

    1:ElasticSearch是什么? Elasticsearch 是一个分布式的免费开源搜索和分析引擎 适用于包括文本、数字、地理空间、结构化和非结构化数据等在内的所有类型的数据…

    数据库 2023年6月6日
    068
  • 笔记-docker学习-2

    继续之前的docker学习 16、 docker commit从容器创建一个新的镜像 OPTIONS说明: -a :提交的镜像作者; -c :使用Dockerfile指令来创建镜像…

    数据库 2023年6月9日
    065
  • 常见的dos命令

    常用快捷键 alt+f4 常见的dos命令 打开CMD的方式 开始+系统+命令提示符 win+R 输入cmd打开控制台 在任意文件夹下,按住shift+鼠标右键点击 资源管理器的地…

    数据库 2023年6月11日
    090
  • 2022的七夕,奉上7个精美的表白代码,同时教大家快速改源码自用

    🤵‍♂️ 个人主页:奇想派👨‍💻 作者简介:奇想派,十年全栈开发经验,团队负责人。喜欢钻研技术,争取成为编程达人 🎖️!🗺️学海无涯苦作舟,🛤️编程之路无悔路!📝 如果文章对你有帮…

    数据库 2023年6月16日
    0101
  • VS code 每次退出都要重新下载解决方案

    VS code 每次退出都要重新下载解决方案 打开文件-首选项-设置 在搜索栏输入Extensions: Auto Update 然后把所有打钩的取消 ,退出vs code 的时候…

    数据库 2023年6月16日
    089
  • mysql8.x docker 远程访问配置

    环境情况 mysql 8.x 是通过 docker 方式部署的,启动的 docker-compose.yml 如下: version: "3.2" servic…

    数据库 2023年5月24日
    061
  • MySQL 分区表,为什么分区键必须是主键的一部分?

    随着业务的不断发展,数据库中的数据量会越来越大,相应地,单表中的数据量也会越来越大,达到临界值时,单表的查询性能会下降。 [En] With the continuous deve…

    数据库 2023年5月24日
    078
  • XtraBackup 搭建从库的一般步骤及 XtraBackup 8.0 的注意事项

    这里,我们重点看看如何基于 XtraBackup 搭建从库。 整个过程其实比较简单,无非是备份和还原。建立复制时唯一需要注意的是位置点的选择,包括: [En] The whole …

    数据库 2023年5月24日
    094
  • VMware下的centOS安装与异常记录

    VMware下的centOS安装与异常记录 随笔 记录在使用虚拟机安装centOs的过程中遇到的一些坑,记录一下,之前发在C**N上的,现在决定在这里重新整理一下,加上一些细节的补…

    数据库 2023年6月6日
    0105
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球