delete删除数据原理

在InndoDB存储引擎中,delete删除操作是把需要删除的数据或者页标记为已删除,后面如果有需要,直接复用即可。这些被标记为已经删除的数据,看起来就像空洞一样。所以看起来虽然delete了,但是表文件大小并不会改变。

如果想删除这些空洞,达到收缩表空间的目的,可以使用alter table t engine=InnoDB来重建表,内部流程如下:

  1. 新建一个表结构相同的表b

  2. 把数据,从表a按照主键递增的顺序一行一行读出来然后插入表b

  3. 操作完毕后,用表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条件,直接查询

整个过程分两步:

  1. InnoDB存储引擎查询数据结果集

  2. 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(*)原理的更多相关文章

  1. 关于mysql 删除数据后物理空间未释放(转载)

    转自 关于mysql 删除数据后物理空间未释放(转载) - NETDATA - 博客园http://www.cnblogs.com/shawnloong/archive/2013/02/07/2908 ...

  2. MySQL删除数据后磁盘空间的释放情况【转】

    OPTIMIZE TABLE 当您的库中删除了大量的数据后,您可能会发现数据文件尺寸并没有减小.这是因为删除操作后在数据文件中留下碎片所致.OPTIMIZE TABLE 是指对表进行优化.如果已经删除 ...

  3. MySQL 删除数据表

    MySQL 删除数据表 MySQL中删除数据表是非常容易操作的, 但是你再进行删除表操作时要非常小心,因为执行删除命令后所有数据都会消失. 语法 以下为删除MySQL数据表的通用语法: DROP TA ...

  4. Mysql删除数据后磁盘空间未释放的解决办法【转】

    转自 Mysql删除数据后,磁盘空间未释放的解决办法 - 今日头条(TouTiao.com)http://toutiao.com/a6303087712678412546/?tt_from=mobil ...

  5. MySQL删除数据几种情况以及是否释放磁盘空间【转】

    MySQL删除数据几种情况以及是否释放磁盘空间: 1.drop table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM ; 2.truncate table tabl ...

  6. 关于mysql 删除数据后(.MYD,MYI)物理空间未释放

    关于mysql 删除数据后物理空间未释放 OPTIMIZE TABLE 当您的库中删除了大量的数据后,您可能会发现数据文件尺寸并没有减小.这是因为删除操作后在数据文件中留下碎片所致.OPTIMIZE ...

  7. 十、MySQL 删除数据表

    MySQL 删除数据表 MySQL中删除数据表是非常容易操作的, 但是你再进行删除表操作时要非常小心,因为执行删除命令后所有数据都会消失. 语法 以下为删除MySQL数据表的通用语法: DROP TA ...

  8. RDS for MySQL 删除数据后空间没有减少处理方法

    公司的程序和数据库部署在阿里云上,数据库使用的是阿里云的RDS,这天,经理在开发群中发了一个信息: 您的RDS实例rm********0oq的磁盘在过去一周平均使用率已超过80.%,建议您对实例规格进 ...

  9. php MySQL 删除数据表

    MySQL 删除数据表 MySQL中删除数据表是非常容易操作的, 但是你再进行删除表操作时要非常小心,因为执行删除命令后所有数据都会消失. 语法 以下为删除MySQL数据表的通用语法: DROP TA ...

  10. 关于mysql 删除数据后物理空间未释放

    转载自:http://www.cnblogs.com/shawnloong/archive/2013/02/07/2908911.html OPTIMIZE TABLE 当您的库中删除了大量的数据后, ...

随机推荐

  1. ICML 2022 | Graph Machine Learning 论文分享

    ICML 2022 | Graph Machine Learning 论文分享 国际机器学习大会(International Conference on Machine Learning,简称ICML ...

  2. [LC646]最长数对链

    题目概述 给出 n 个数对. 在每一个数对中,第一个数字总是比第二个数字小. 现在,我们定义一种跟随关系,当且仅当 b < c 时,数对(c, d) 才可以跟在 (a, b) 后面.我们用这种形 ...

  3. python创建项目虚拟环境

    创建一个文件夹用于存放你的虚拟环境 cd 到存放虚拟环境的地址 安装虚拟环境库: pip3 install virtualenv 创建虚拟环境:python3 -m venv 环境名称 激活虚拟环境: ...

  4. Solution -「PKUWC 2018」「洛谷 P5298」Minimax

    \(\mathscr{Description}\)   Link.   给定一棵二叉树,每片叶子有一个权值,所有权值互不相同.每个非叶结点 \(u\) 有一个概率 \(p_u\in(0,1)\),表示 ...

  5. .net core 用 identitymodel 请求token。

    identitymodel  也有在Nuget里搜索和安装. identitymodel 扩展了HttpClient的一些方法用于token请求. 例如:client.RequestTokenAsyn ...

  6. Forrester Wave™报告:天翼云三项产品能力获评最高分!

    8月5日,国际权威研究机构Forrester发布了<Forrester Wave: 中国公有云平台厂商评测,2024Q3>报告.中国电信天翼云凭借前瞻性的发展战略和领先的产品能力,跻身行业 ...

  7. spring boot配置mybatis-plus

    一.maven配置 <mybatis-plus.version>3.2.0</mybatis-plus.version> <mysql-connector.version ...

  8. 理解 SystemVerilog 中的循环与并发线程

    1. 首先理解 scope 的概念 除了常见的module.interface.class.task以及function等等,另外,begin-end block 和 fork-join block ...

  9. 用 just 简化项目命令管理

    在软件开发过程中,高效管理项目命令是提升开发效率的关键, 它们可以帮助我们自动化重复的任务,简化项目管理流程,提高效率. 今天,我们来介绍一个名为 just 的任务运行器. 它由 Casey 发起,用 ...

  10. VS2019 找不到资产文件 “xxxx\obj\project.assets.json”运行NuGet包还原以生成此文件

    参考地址:https://blog.csdn.net/weixin_42835409/article/details/107033059 下载 log4net 源码打开,编译报错: 严重性 代码 说明 ...