MySQL-删除数据和count(*)原理
delete删除数据原理
在InndoDB存储引擎中,delete删除操作是把需要删除的数据或者页标记为已删除,后面如果有需要,直接复用即可。这些被标记为已经删除的数据,看起来就像空洞一样。所以看起来虽然delete了,但是表文件大小并不会改变。
如果想删除这些空洞,达到收缩表空间的目的,可以使用alter table t engine=InnoDB来重建表,内部流程如下:
新建一个表结构相同的表b
把数据,从表a按照主键递增的顺序一行一行读出来然后插入表b
操作完毕后,用表b替换表a
在mysql5.6之前,这个操作在整个过程中,不能有更新操作。mysql5.6以后引入的Online DDL,可以对上面的步骤进行优化。
首先,复习一下onlineDDL的概念:在之前的笔记MySQL-全句锁、表锁和元数据锁中,学习元数据锁的时候也提到过online DDL的概念,核心就是先申请一个MDL写锁,成功以后会降级为MDL读锁,然后做真正的DDL操作,操作完毕后再申请MDL写锁。
其次,在做真正的DDL操作时,既然不阻塞DML操作,那么对表的DML操作如何体现到新表中呢?MySQL的实现是把对表的更新操作记录在一个日志文件(row log)中,等到拷贝完原数据到到临时表后,再对这个临时表应用row log中的修改。
count(*)原理
在不同的存储引擎中,对count(*)的实现是不同的
MyISAM中,会保存总行数到磁盘中,每次select count(*)会直接返回这个值
InnoDB中,计算count(*)的时候,需要把数据从引擎中一行一行读出来,然后计算累加值
为什么InnoDB不把数据保存起来?
在之前的文章 MySQL-事务中的一致性读和锁定读的具体原理中,我们学习过事务,了解了MVCC,知道不同时刻启动的事务,拿到的事务视图是不一样的,在可重复读的隔离级别设置下,事务中读取数据始终是一致的。这个问题其实就和MVCC有关,既然每个事务视图拿到的数据可能是不一样的,那么就无法只存储一个值,来代表行数。而且,MyISAM看起来把行数存储为一个值,查询的时候性能较高,但是一旦查询条件中使用了where,那么就无法使用这个值了。
不同count写法的性能对比
首先需要明确,count(XX),统计的是XX不为null的行数。
在实际统计时,有人会用count(*),有人用count(1),还有其他用count(字段)的,那么这些写法有什么差别呢?
我们假设没有where条件,直接查询
整个过程分两步:
InnoDB存储引擎查询数据结果集
Server层根据结果集进行遍历统计
InnoDB存储引擎查询数据结果集时
InnoDB会在所有的索引中,选择一个最小的索引来进行数据查询
如果有普通索引,就用最小的普通索引
如果没有普通索引,用主键索引
针对不同的查询写法,返回的数据结果集中的取值也不同
count(1)和count(*):InnoDB存储引擎返回对应的数据列表,但是不取值,可以理解为返回一个List 但是data中没有任何字段的。
count(字段):InnoDB存储引擎返回对应的数据列表,需要取得对应字段的值
Server层根据结果集进行遍历统计
count(1)和count(*):server层拿到数据后
如果是count(1):server层在每行插入一个1,因为1肯定不为null,所以直接遍历统计行数
如果是count(*):server层直接遍历统计行数
count(字段):
如果是主键id和定义时不为空的字段:server层直接进行遍历统计,和count(1)和count(*)比,还有复制字段的开销
定义时可以为空的字段:server层需要取出字段,再判断一下是否为null,不为空的才统计
总结
在没有where查询条件时,我们可以看到,不同count写法的性能优劣如下:
count(*) ≈count(1) > count(字段)
MySQL-删除数据和count(*)原理的更多相关文章
- 关于mysql 删除数据后物理空间未释放(转载)
转自 关于mysql 删除数据后物理空间未释放(转载) - NETDATA - 博客园http://www.cnblogs.com/shawnloong/archive/2013/02/07/2908 ...
- MySQL删除数据后磁盘空间的释放情况【转】
OPTIMIZE TABLE 当您的库中删除了大量的数据后,您可能会发现数据文件尺寸并没有减小.这是因为删除操作后在数据文件中留下碎片所致.OPTIMIZE TABLE 是指对表进行优化.如果已经删除 ...
- MySQL 删除数据表
MySQL 删除数据表 MySQL中删除数据表是非常容易操作的, 但是你再进行删除表操作时要非常小心,因为执行删除命令后所有数据都会消失. 语法 以下为删除MySQL数据表的通用语法: DROP TA ...
- Mysql删除数据后磁盘空间未释放的解决办法【转】
转自 Mysql删除数据后,磁盘空间未释放的解决办法 - 今日头条(TouTiao.com)http://toutiao.com/a6303087712678412546/?tt_from=mobil ...
- MySQL删除数据几种情况以及是否释放磁盘空间【转】
MySQL删除数据几种情况以及是否释放磁盘空间: 1.drop table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM ; 2.truncate table tabl ...
- 关于mysql 删除数据后(.MYD,MYI)物理空间未释放
关于mysql 删除数据后物理空间未释放 OPTIMIZE TABLE 当您的库中删除了大量的数据后,您可能会发现数据文件尺寸并没有减小.这是因为删除操作后在数据文件中留下碎片所致.OPTIMIZE ...
- 十、MySQL 删除数据表
MySQL 删除数据表 MySQL中删除数据表是非常容易操作的, 但是你再进行删除表操作时要非常小心,因为执行删除命令后所有数据都会消失. 语法 以下为删除MySQL数据表的通用语法: DROP TA ...
- RDS for MySQL 删除数据后空间没有减少处理方法
公司的程序和数据库部署在阿里云上,数据库使用的是阿里云的RDS,这天,经理在开发群中发了一个信息: 您的RDS实例rm********0oq的磁盘在过去一周平均使用率已超过80.%,建议您对实例规格进 ...
- php MySQL 删除数据表
MySQL 删除数据表 MySQL中删除数据表是非常容易操作的, 但是你再进行删除表操作时要非常小心,因为执行删除命令后所有数据都会消失. 语法 以下为删除MySQL数据表的通用语法: DROP TA ...
- 关于mysql 删除数据后物理空间未释放
转载自:http://www.cnblogs.com/shawnloong/archive/2013/02/07/2908911.html OPTIMIZE TABLE 当您的库中删除了大量的数据后, ...
随机推荐
- Solution -「NOI 2017」「洛谷 P3826」蔬菜
\(\mathscr{Description}\) Link. 原题意比较简洁了.注意一下卖出的菜也会变质,且让它们代替未卖出的菜变质是更优的. \(\mathscr{Solution}\) ...
- 史上最全memcached面试26题和答案
Memcached是什么? Memcached是一个开源的,高性能的内存绶存软件,从名称上看Mem就是内存的意思,而Cache就是缓存的意思. Memcached的作用? Memcached的作用:通 ...
- nginx详细参数配置(史上最全)
Nginx (engine x) 是一个轻量级高性能的HTTP和反向代理服务器,同时也是一个通用 代理服务器 (TCP/UDP/IMAP/POP3/SMTP),最初由俄罗斯人Igor Sysoev编写 ...
- Elasticsearch(4)--- 基本概念(Index、Type、Document、集群、节点、分片及副本、倒排索引)
这篇博客讲到基本概念包括: Index.Type.Document.集群,节点,分片及副本,倒排索引. 一.Index.Type.Document 1.Index index:索引是文档(Docume ...
- 解决安装python各种包速度慢问题
# 改用清华镜像库 pip install ******* -i https://pypi.tuna.tsinghua.edu.cn/simple
- IOC 操作Bean管理(xml 注入集合属性)+(bean 作用域)
1.注入数组类型属性2.注入 List 集合类型属性3.注入 Map 集合类型属性(1)创建类,定义数组.list.map.set 类型属性,生成对应 set 方法 public class Stu ...
- 一种把dump里连续的内存保存到文件的方法
前几天调试一个崩溃,截到一个full dump文件,显示一个视频帧数据转换有问题.从调用栈可以看到完整的帧数据. 然后我就想把这个数据保存下来,再构造崩溃场景,VS没有提供把内存dump为文件的功能. ...
- RabbitMq消息过期时间TTL介绍
概述: 在rabbitmq中我们可以给消息设定过期时间LLT(Time to Live),在消息发送后过期时间段内未被消费,则系统会将其删除,被删除的消息将会进入死信队列.关于设置消息的过期时间有两种 ...
- 一款基于 WPF 开源、功能全面的串口调试工具
前言 今天大姚给大家分享一款基于 WPF 开源(MIT License).免费.功能全面的串口调试工具:BYSerial. 项目介绍 BYSerial是一款基于 WPF 开源(MIT License) ...
- Asp.Net Core3.0 微信退款
参考文档: 微信支付申请退款API文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_8_11.shtml (最新更新时间:2022 ...