MySQL45讲 第十四讲 count(*)这么慢,我该怎么办?

文章目录

  • MySQL45讲 第十四讲 count(*)这么慢,我该怎么办?
    • 一、count (*) 实现方式及性能问题
      • (一)不同引擎的实现差异
      • (二)InnoDB 的优化措施
    • 二、计数方案探讨
      • (一)缓存系统保存计数
      • (二)数据库保存计数
    • 三、count 不同用法的性能差别
      • (一)语义解释
      • (二)性能对比
    • 四、总结

MySQL45讲 第十四讲 count(*)这么慢,我该怎么办?


一、count (*) 实现方式及性能问题

(一)不同引擎的实现差异

  1. MyISAM 引擎将表的总行数存储在磁盘上,执行count (*)时可直接返回,效率高。但 MyISAM 不支持事务。如果加了where 条件的话,MyISAM表也是不能返回得这么快的。
  2. 在实际应用中,InnoDB 引擎使用更为广泛。InnoDB引擎执行 count (*)时,需逐行读取数据并累积计数,这是因为在多版本并发控制(MVCC)机制下,不同事务对表总行数的 “可见性” 不同。例如,在一个同时有事务插入数据的场景中,不同时刻启动的事务查询 count (*) 可能得到不同结果,所以 InnoDB只能逐行判断每行记录是否对当前查询可见,进而确定总行数。

(二)InnoDB 的优化措施

  1. InnoDB 是索引组织表,普通索引树比主键索引树小。对于 count (*) 操作:
    • MySQL优化器会选择遍历最小的索引树以减少扫描数据量。然而,即便如此,随着表中记录数增多,直接使用 count (*) 仍会导致性能问题。
    • show table status 命令虽执行快,但其中的TABLE_ROWS 值是通过采样估算得来,误差可达 40% - 50%,不能准确替代 count (*) 使用。

二、计数方案探讨

(一)缓存系统保存计数

  1. 对于更新频繁的库,可使用 Redis 等缓存系统保存表的总行数,表数据插入或删除时相应更新 Redis 计数。但这种方式存在问题:
    • 缓存系统可能丢失更新。即使将 Redis 数据持久化存储,仍可能因异常重启等情况丢失计数更新操作
    • 逻辑上不精确。在并发系统中,由于操作顺序难以精确控制,可能出现数据不一致情况,如页面显示的记录与 Redis 计数不匹配。

(二)数据库保存计数

  1. 将计数直接存于数据库单独的计数表 C 中,利用 InnoDB 支持事务的特性,可解决崩溃丢失问题。在事务执行过程中,通过合理的事务隔离机制,可确保计数与表数据在逻辑上的一致性,避免了缓存系统中因并发操作导致的计数不精确问题。

三、count 不同用法的性能差别

(一)语义解释

  1. count () 是聚合函数,对于返回结果集逐行判断,参数非 NULL 时累计值加 1。count (*)、count (主键 id) 和 count (1) 都返回满足条件结果集的总行数,count (字段) 返回满足条件数据行中参数 “字段” 不为 NULL 的总个数。

(二)性能对比

  1. 对于 count (主键 id),InnoDB 引擎遍历整张表取每行 id 值返回给 server 层,server 层判断非空后累加,涉及解析数据行和拷贝字段值操作:
    • count (1) 则遍历整张表但不取值,server 层每行放数字 “1” 判断非空后累加,所以 count (1) 比 count (主键 id) 执行快。
    • count (字段) 若字段定义为 not null,逐行读取判断非空累加,若字段允许为 null,还需取值进一步判断,性能较差。
    • count (*) 专门优化不取值,按行累加,效率较高。建议尽量使用 count (*)
  2. 按照效率排序的话,count(字段)<count(主键id)<count(1)≈count(*),所以尽量使用count(*)

四、总结

  1. MySQL 中不同引擎 count (*) 实现方式不同,InnoDB 因 MVCC 机制不能像 MyISAM 直接返回总行数
  2. 在处理频繁变更且需统计表行数的需求时,Redis缓存系统保存计数虽读写快但存在丢失更新和逻辑不精确问题。而在数据库中利用事务特性,把这个计数直接放到数据库里单独的一张计数表C中,保存计数可解决一致性问题。
  3. 同时,了解 count 不同用法性能差别有助于优化查询语句,count(字段)<count(主键id)<count(1)≈count(*),在实际应用中应根据具体需求选择合适的计数方案,充分发挥 InnoDB 引擎事务特性简化业务逻辑,确保数据的准确性和系统性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/464484.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDC报告解读:实用型靶场将成为下一代网络靶场的必然方向

——赛宁网安&#xff1a;回归用户需求&#xff0c;开创实用型靶场新范式 导读 本文基于《IDC TechScape&#xff1a;中国网络安全软件技术发展路线图&#xff0c;2024》中关于网络安全实训演练测试平台&#xff08;靶场&#xff09;的技术路线分析&#xff0c;结合国内外靶场…

RESTful风格

目录 一、什么是RESTful 1.1 RESTFul对WEB服务接口的规定包括&#xff1a; 1.2 REST对请求方式的具体约束如下&#xff1a; 1.3 REST对URL的具体约束如下&#xff1a; 1.4 RESTFul的核心概念&#xff1a; 二、RESTful风格与传统方式对比 三、RESTful风格演示 3.1 查询所…

openapi回调地址请求不通过

目录 1. 验证url接口get请求本地自测报错 2. 测试回调模式成功不返回结果 3. 测试回调模式返回结果带双引号 对接企业微信 产生会话回调事件 接口问题解决 1. 验证url接口get请求本地自测报错 java.lang.IllegalArgumentException: Last encoded character (before the pa…

砥砺十年风雨路,向新而行创新程丨怿星科技十周年庆典回顾

10月24日&#xff0c;是一年中的第256天&#xff0c;也是程序员节&#xff0c;同时也是怿星的生日。2014年到2024年&#xff0c;年华似水匆匆一瞥&#xff0c;多少岁月轻描淡写&#xff0c;怿星人欢聚一堂&#xff0c;共同为怿星科技的十周年庆生&#xff01; 01.回忆往昔&…

C++:AVL树

目录 AVL树概念 AVL树的实现 AVL树的节点 AVL树的插入 AVL树的平衡调整 右单旋 左单旋 左右双旋 右左双旋 完整的插入函数 AVL树的查找 AVL树的验证 验证有序 验证平衡 完整代码 AVL树概念 AVL树是一种具有特殊性质的二叉搜索树&#xff0c;AVL树的左右子树也都…

Nginx线程模型

Nginx的线程模型具有其独特的设计特点&#xff0c;主要基于多进程和异步非阻塞的处理机制。以下是对Nginx线程模型的详细解析&#xff1a; 一、多进程模型 Nginx采用的是多进程模型&#xff0c;而非多线程模型。在这种模型中&#xff0c;Nginx会启动一个master进程和多个work…

【HTML】——VSCode 基本使用入门和常见操作

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 零&#xff1a;HTML开发工具VSCode的使用 1&#xff1a;创建项目 2&#xff1a;创建格式模板&#x…

【C/C++】【三种方法】模拟实现strlen

学习目标&#xff1a; 使用代码模拟实现strlen。 逻辑&#xff1a; strlen 需要输入一个字符串数组类型的变量&#xff0c;并且返回一个整型类型的数据。strlen 需要计算字符串数组有多少个元素。 代码1&#xff1a;使用计数器 #define _CRT_SECURE_NO_WARNINGS 1 #include&…

【双指针】【数之和】 LeetCode 633.平方数之和

算法思想&#xff1a; 双指针枚举i,j&#xff1b;类似三数之和 class Solution { public:bool judgeSquareSum(int c) {long long sum0;vector<int> dp;dp.push_back(0);long long start1;while(sum < c){sum start *start;if(sum>c) break;else dp.push_back(…

HarmonyOS Next星河版笔记--界面开发(3)

属性 1.1.设计资源-svg图标 需求&#xff1a;界面中展示图标→可以使用的svg图标(任意放大缩小不失真、可以改变颜色) 使用方式&#xff1a; ①设计师提供&#xff1a;基于项目的图标&#xff0c;拷贝到项目目录使用 Image($r(app.media.ic_dianpu)) .width(40) fillColor…

解决方案 | 部署更快,自动化程度高!TOSUN同星线控底盘解决方案

Tosun——线控底盘解决方案 在汽车智能化和电动化进程中&#xff0c;智能线控底盘相关的核心技术和产品成为了新能源汽车及智能驾驶产业的重点发展方向。同星智能作为行业先行者&#xff0c;精研汽车电子行业整体解决方案&#xff0c;提供基于TSMaster的底盘HIL仿真测试解决方…

分布式光伏管理办法

随着分布式光伏项目的不断增加&#xff0c;传统的管理方式已经难以满足高效、精准的管理需求。光伏业务管理系统作为一种集信息化、智能化于一体的管理工具&#xff0c;正在逐步成为分布式光伏项目管理的重要支撑。 光伏业务管理系统通过数字化手段实现对光伏业务全流程的精细化…

细腻的链接:C++ list 之美的解读

细腻的链接&#xff1a;C list 之美的解读 前言&#xff1a; 小编在前几日刚写过关于vector容器的内容&#xff0c;现在小编list容器也学了一大部分了&#xff0c;小编先提前说一下学这部分的感悟&#xff0c;这个部分是我学C以来第一次感到有难度的地方&#xff0c;特别是在…

文件操作案例

文件操作&#xff08;帮助小学生控诉妈妈&#xff09;:###无任何不良指导###

基于 RNN 的语言模型

基于 RNN 的语言模型 循环神经网络&#xff08;Recurrent Neural Network, RNN&#xff09;是一类网络连接中包含环路的 神经网络的总称。 给定一个序列&#xff0c;RNN 的环路用于将历史状态叠加到当前状态上。沿着时间维度&#xff0c;历史状态被循环累积&#xff0c;并作为…

嵌入式硬件工程师的职业发展规划

嵌入式硬件工程师可以按照以下阶段进行职业发展规划&#xff1a; 1. **初级阶段&#xff08;1-3 年&#xff09; ** - **技术学习与积累**&#xff1a; **电路基础强化**&#xff1a; 深入学习模拟电路和数字电路知识&#xff0c;能够熟练分析和设计基本的电路&#xff0c;…

C#:强大而优雅的编程语言

在当今的软件开发领域&#xff0c;C#作为一种广泛应用的编程语言&#xff0c;以其强大的功能、优雅的语法和丰富的生态系统&#xff0c;受到了众多开发者的喜爱。本文将深入探讨 C#的各个方面&#xff0c;展示它的魅力和优势。 一、C#的历史与发展 C#是由微软公司开发的一种面…

时间序列预测(十八)——实现配置管理和扩展命令行参数解析器

如图&#xff0c;这是一个main,py文件&#xff0c;在此代码中&#xff0c;最开始定义了许多模型参数&#xff0c;为了使项目更加灵活和可扩展&#xff0c;便于根据不同的需求调整参数和配置&#xff0c;可以根据实际需要扩展参数和配置项。 下面是如何实现配置管理和扩展命令行…

影刀RPA实战:嵌入python,如虎添翼

1. 影刀RPA与Python的关系 影刀RPA与Python的关系可以从以下几个方面来理解&#xff1a; 技术互补&#xff1a;影刀RPA是一种自动化工具&#xff0c;它允许用户通过图形化界面创建自动化流程&#xff0c;而Python是一种编程语言&#xff0c;常用于编写自动化脚本。影刀RPA可以…

GR2——在大规模视频数据集上预训练且机器人数据上微调,随后预测动作轨迹和视频(含GR1详解)

前言 上个月的24年10.9日&#xff0c;我在朋友圈看到字节发了个机器人大模型GR2&#xff0c;立马去看了下其论文(当然了&#xff0c;本质是个技术报告) 那天之后&#xff0c;我就一直想解读这个GR2来着 然&#xff0c;意外来了&#xff0c;如此文《OmniH2O——通用灵巧且可全…