it编程 > 数据库 > Mysql

为什么说MySQL不建议使用delete删除数据

6人参与 2026-03-18 Mysql

这篇文章,我将从 innodb 存储空间分配delete 对性能的影响 以及 最佳实践建议 三个角度,逐步剖析为什么不推荐直接使用 delete 删除大批量数据。

一、innodb 存储架构概览

extent 自动扩展策略

  1. 初始分配为 1 个 extent
  2. 若总表空间 < 32mb,每次 +1 个 extent
  3. 大于 32mb,则每次 +4 个 extent

二、innodb 表空间类型

  1. 系统表空间 (ibdata1),保存内部字典等元数据。
  2. 独立表空间innodb_file_per_table=on),每个表一个 .ibd 文件。
  3. undo 表空间,存储 mvcc 的回滚段。

从 mysql 8.0 起,支持自定义通用表空间

create tablespace tbs_hot
  add datafile '/hot_data/tbs_hot01.dbf'
  initial_size = 10g
  autoextend_size = 1g
  max_size = 32g
  engine = innodb;

冷热分离

  • 热数据 (用户、订单) → ssd 表空间
  • 冷数据 (日志、归档) → hdd 表空间

三、实际演示:空间分配 & 回收

1. 创建空表

create table user (
  id           bigint primary key auto_increment,
  name         varchar(20) not null,
  age          tinyint      not null,
  gender       char(1)      not null,
  phone        varchar(16)  not null,
  create_time  datetime     not null default current_timestamp,
  update_time  datetime     not null
) engine=innodb;
$ ls -lh user.ibd
-rw-r----- 1 mysql mysql 96k nov  6 12:48 user.ibd

说明:空表首个 extent(32 页)占用约 96kb。

2. 插入 10w 条

call insert_user_data(100000);  -- 自定义存储过程批量插入
$ ls -lh user.ibd
-rw-r----- 1 mysql mysql 14m nov  6 10:58 user.ibd

3. delete 50k 条

delete from user limit 50000;
$ ls -lh user.ibd
-rw-r----- 1 mysql mysql 14m nov  6 13:22 user.ibd

四、delete 对查询性能的影响

初始查询(100w 条+索引)

select id, age, phone
  from user
 where name like 'lyn12%';

删除 50w 后再查

delete from user limit 500000;
analyze table user;
select id, age, phone
  from user
 where name like 'lyn12%';

结论:大表删除半数数据后,查询成本和 i/o 基本不变,只是返回结果不同。

五、为什么不推荐大批量 delete

  1. 空间不回收

    • .ibd 文件不缩小,extents 保留
  2. 页碎片

    • 随机删除/更新导致页分裂、空洞增加
  3. 后续写入难用

    • 删除标记页只有在插入更小行时才会重用
  4. 碎片回收代价高

    • alter table … engine=innodb:全表重建,i/o 密集、阻塞 dml

六、最佳实践与优化建议

1. 逻辑删除(标记删除)

alter table user
  add column is_deleted tinyint not null default 0;

update user
   set is_deleted = 1
 where id = 123456;

-- 查询时统一过滤:
select * 
  from user
 where is_deleted = 0
   and name like 'lyn12%';

2. 分区归档

alter table ota_order_bak
  exchange partition p202301
  with table ota_order_mid;

通过分区操作,瞬间移动大块数据,无需耗时 delete。

3. 权限隔离

create user 'svc_user'@'%'
  identified by '…';
grant select, insert, update
  on db_user.*;

4. 专用归档系统

七、总结

到此这篇关于为什么说mysql不建议使用delete删除数据的文章就介绍到这了,更多相关mysql不使用delete删除数据内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

MySQL CRUD 查询、插入、更新、删除全实战指南

03-18

mysql 键长如何计算的方法实现

03-18

举例详解Tomcat与Nginx、Apache的区别是什么

03-18

MySQL EXPLAIN 中 type 字段示例详解

03-18

mysql行转列(7种方法)和列转行的实现

03-18

阿里云服务器MySQL与nacos配置

03-18

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论