【架构】-- Mysql delete vs truncate 深度解析

目录

[Mysql delete 和 truncate 区别深度解析](#Mysql delete 和 truncate 区别深度解析)

一、前言

[二、MySQL 中 DELETE 与 TRUNCATE 的区别](#二、MySQL 中 DELETE 与 TRUNCATE 的区别)

1、基本语法

DELETE

TRUNCATE

三、核心区别总览

[四、DELETE 底层原理](#四、DELETE 底层原理)

[1、DELETE 是逐行删除](#1、DELETE 是逐行删除)

[2、DELETE 支持事务回滚](#2、DELETE 支持事务回滚)

[3、DELETE 不会重置 AUTO_INCREMENT](#3、DELETE 不会重置 AUTO_INCREMENT)

[五、TRUNCATE 底层原理](#五、TRUNCATE 底层原理)

[1、TRUNCATE 本质是 DDL](#1、TRUNCATE 本质是 DDL)

[2、TRUNCATE 执行速度非常快](#2、TRUNCATE 执行速度非常快)

[3、TRUNCATE 会重置 AUTO_INCREMENT](#3、TRUNCATE 会重置 AUTO_INCREMENT)

[4、TRUNCATE 通常不可回滚](#4、TRUNCATE 通常不可回滚)

[六、MySQL InnoDB 深度分析](#六、MySQL InnoDB 深度分析)

[1、DELETE 的 InnoDB 行为](#1、DELETE 的 InnoDB 行为)

[2、TRUNCATE 的 InnoDB 行为](#2、TRUNCATE 的 InnoDB 行为)

七、锁机制区别

DELETE

TRUNCATE

[八、大表 DELETE 的问题](#八、大表 DELETE 的问题)

[1、为什么大表 DELETE 很危险](#1、为什么大表 DELETE 很危险)

2、正确做法

分批删除

使用分区表

使用归档表

[九、binlog 区别](#九、binlog 区别)

DELETE

TRUNCATE

[十、PostgreSQL 中的区别](#十、PostgreSQL 中的区别)

1、DELETE

2、TRUNCATE

[3、PostgreSQL 特点](#3、PostgreSQL 特点)

[十一、StarRocks 中的区别](#十一、StarRocks 中的区别)

[1、DELETE 特点](#1、DELETE 特点)

[2、StarRocks DELETE 原理](#2、StarRocks DELETE 原理)

[3、TRUNCATE TABLE](#3、TRUNCATE TABLE)

[4、StarRocks 更推荐的方案](#4、StarRocks 更推荐的方案)

[DROP PARTITION](#DROP PARTITION)

[INSERT OVERWRITE](#INSERT OVERWRITE)

十二、多数据库横向对比

十三、生产环境建议

1、小数据量

2、大数据量

[3、OLAP 场景](#3、OLAP 场景)

十四、面试高频问题

[问:DELETE 与 TRUNCATE 最大区别是什么?](#问:DELETE 与 TRUNCATE 最大区别是什么?)

[问:TRUNCATE 为什么快?](#问:TRUNCATE 为什么快?)

[问:DELETE 为什么可能导致主从延迟?](#问:DELETE 为什么可能导致主从延迟?)

[问:为什么 OLAP 不适合频繁 DELETE?](#问:为什么 OLAP 不适合频繁 DELETE?)

十五、总结


Mysql delete 和 truncate 区别深度解析

一、前言

在日常数据库开发与运维过程中,DELETE 与 TRUNCATE 是两个非常常见的数据清理命令。

很多开发人员认为:

  • DELETE 是删除数据

  • TRUNCATE 也是删除数据

于是简单认为两者只是"语法不同"。

实际上,这种理解并不完整。

在生产环境中:

  • 执行速度

  • 锁机制

  • 回滚能力

  • 自增 ID

  • binlog 日志

  • 主从复制

  • 磁盘空间

  • MVCC

  • WAL

  • 元数据管理

都会受到 DELETE 和 TRUNCATE 的影响。

尤其在:

  • 大数据量删除

  • 数据归档

  • 数据湖

  • OLAP 引擎

  • 分布式数据库

场景下,两者差异会更加明显。

本文将从:

  • MySQL

  • PostgreSQL

  • StarRocks

三个数据库角度,深入分析 DELETE 与 TRUNCATE 的区别。


二、MySQL 中 DELETE 与 TRUNCATE 的区别

1、基本语法

DELETE

复制代码
DELETE FROM user_info WHERE id = 1;

TRUNCATE

复制代码
TRUNCATE TABLE user_info;

三、核心区别总览

对比项 DELETE TRUNCATE
类型 DML DDL
是否逐行删除 是 否
是否记录每行日志 是 否
是否可带 WHERE 支持 不支持
是否可回滚 一般可回滚 大多数情况不可回滚
是否重置自增 ID 不会 会
执行速度 慢 快
是否触发 DELETE Trigger 会 不会
锁类型 行锁 表锁
是否释放空间 不一定 通常会
binlog 量 大 小

四、DELETE 底层原理

1、DELETE 是逐行删除

DELETE 本质属于:

复制代码
DML(Data Manipulation Language)

执行过程:

  1. 找到符合条件的数据

  2. 一行一行删除

  3. 记录 undo log

  4. 记录 redo log

  5. 记录 binlog

  6. 更新索引

  7. 更新 MVCC 信息

例如:

复制代码
DELETE FROM order_info WHERE create_time < '2025-01-01';

数据库需要:

  • 扫描数据

  • 找到符合条件的行

  • 更新聚簇索引

  • 更新二级索引

  • 写入事务日志

因此:

数据量越大,DELETE 越慢。


2、DELETE 支持事务回滚

例如:

复制代码
BEGIN;
​
DELETE FROM user_info WHERE id = 1;
​
ROLLBACK;

数据会恢复。

原因:

DELETE 会写 undo log。


3、DELETE 不会重置 AUTO_INCREMENT

例如:

复制代码
DELETE FROM user_info;

再插入:

复制代码
INSERT INTO user_info(name) VALUES('Tom');

ID 可能继续增长:

复制代码
10001

不会重新从 1 开始。


五、TRUNCATE 底层原理

1、TRUNCATE 本质是 DDL

TRUNCATE 属于:

复制代码
DDL(Data Definition Language)

很多数据库内部实现:

复制代码
DROP + CREATE

或者:

复制代码
快速重建数据文件

因此:

TRUNCATE 不需要逐行删除。


2、TRUNCATE 执行速度非常快

例如:

复制代码
TRUNCATE TABLE log_info;

数据库通常:

  • 直接清空数据页

  • 重置元数据

  • 重建表空间

不扫描每一行数据。

因此:

即使亿级数据:

TRUNCATE 也可能秒级完成。


3、TRUNCATE 会重置 AUTO_INCREMENT

例如:

复制代码
TRUNCATE TABLE user_info;

再次插入:

复制代码
INSERT INTO user_info(name) VALUES('Tom');

ID 会重新从:

复制代码
1

开始。


4、TRUNCATE 通常不可回滚

在 MySQL 中:

复制代码
TRUNCATE TABLE user_info;

会隐式提交事务。

即使:

复制代码
BEGIN;
TRUNCATE TABLE user_info;
ROLLBACK;

通常也无法恢复。


六、MySQL InnoDB 深度分析

1、DELETE 的 InnoDB 行为

DELETE 会:

  • 写 undo log

  • 写 redo log

  • 更新聚簇索引

  • 更新二级索引

  • 保留 MVCC 版本链

因此:

大量 DELETE 容易:

  • 产生大量碎片

  • 导致 purge lag

  • 导致 undo 膨胀

  • 导致 IO 飙升


2、TRUNCATE 的 InnoDB 行为

TRUNCATE:

  • 不逐行删除

  • 不生成大量 undo

  • 不维护旧版本链

通常直接:

复制代码
重建表

因此性能极高。


七、锁机制区别

DELETE

DELETE 使用:

复制代码
行锁(Row Lock)

例如:

复制代码
DELETE FROM user_info WHERE id = 1;

只锁部分数据。

并发性能较好。


TRUNCATE

TRUNCATE 使用:

复制代码
表锁(Table Lock)

整个表不可读写。

因此:

线上高并发环境需要谨慎。


八、大表 DELETE 的问题

1、为什么大表 DELETE 很危险

例如:

复制代码
DELETE FROM order_info;

可能导致:

  • 主从延迟

  • binlog 暴涨

  • undo 暴涨

  • IO 飙升

  • 锁等待

  • CPU 飙升

尤其:

千万级数据表。


2、正确做法

分批删除

复制代码
DELETE FROM order_info
WHERE create_time < '2024-01-01'
LIMIT 1000;

循环执行。


使用分区表

复制代码
ALTER TABLE order_info DROP PARTITION p202401;

速度远超 DELETE。


使用归档表

先归档:

复制代码
INSERT INTO order_history
SELECT * FROM order_info
WHERE create_time < '2024-01-01';

再删除。


九、binlog 区别

DELETE

DELETE 会记录:

复制代码
每一行变更

binlog 非常大。


TRUNCATE

TRUNCATE 只记录:

复制代码
DDL 操作

binlog 很小。


十、PostgreSQL 中的区别

1、DELETE

PostgreSQL DELETE:

  • 采用 MVCC

  • 不会立即删除数据

  • 只是标记为 dead tuple

因此:

需要:

复制代码
VACUUM

回收空间。


2、TRUNCATE

PostgreSQL TRUNCATE:

  • 速度极快

  • 支持 RESTART IDENTITY

  • 支持 CASCADE

例如:

复制代码
TRUNCATE TABLE user_info RESTART IDENTITY;

3、PostgreSQL 特点

PostgreSQL 的 TRUNCATE:

居然支持事务回滚。

例如:

复制代码
BEGIN;
​
TRUNCATE TABLE user_info;
​
ROLLBACK;

数据可以恢复。

这一点与 MySQL 不同。


十一、StarRocks 中的区别

1、DELETE 特点

StarRocks 属于:

复制代码
MPP OLAP 数据库

DELETE 不适合频繁使用。

因为:

OLAP 引擎更适合:

  • 批量写入

  • 批量覆盖

  • 分区替换


2、StarRocks DELETE 原理

DELETE 通常:

  • 标记删除

  • 后台 Compaction 清理

因此:

频繁 DELETE 会影响查询性能。


3、TRUNCATE TABLE

StarRocks:

复制代码
TRUNCATE TABLE table_name;

会快速清空数据。

速度远高于 DELETE。


4、StarRocks 更推荐的方案

实际生产中:

更推荐:

DROP PARTITION

复制代码
ALTER TABLE order_info DROP PARTITION p202501;

或者:

INSERT OVERWRITE

因为:

OLAP 引擎更适合:

复制代码
批量替换

而不是逐行删除。


十二、多数据库横向对比

数据库 DELETE TRUNCATE
MySQL DML,逐行删除 DDL,快速清空
PostgreSQL MVCC 标记删除 支持事务回滚
StarRocks 不适合高频 DELETE 推荐快速清空
Oracle 支持回滚机制复杂 高性能 DDL
SQL Server 逐行记录日志 页级快速释放

十三、生产环境建议

1、小数据量

推荐:

复制代码
DELETE

原因:

  • 灵活

  • 支持 WHERE

  • 支持回滚


2、大数据量

推荐:

  • TRUNCATE

  • DROP PARTITION

  • 分区表

  • 数据归档

避免:

复制代码
DELETE 全表

3、OLAP 场景

推荐:

  • INSERT OVERWRITE

  • PARTITION REPLACE

  • DROP PARTITION

不推荐高频 DELETE。


十四、面试高频问题

问:DELETE 与 TRUNCATE 最大区别是什么?

答:

DELETE 是 DML,逐行删除。

TRUNCATE 是 DDL,直接清空表。


问:TRUNCATE 为什么快?

答:

因为不逐行删除。

通常直接:

  • 重建表

  • 重置元数据

  • 释放数据页


问:DELETE 为什么可能导致主从延迟?

答:

因为:

  • binlog 巨大

  • 每行都写日志

  • 从库需要逐行回放


问:为什么 OLAP 不适合频繁 DELETE?

答:

因为:

OLAP 更适合:

  • 批量导入

  • 批量覆盖

  • 分区替换

逐行 DELETE 会导致:

  • Compaction 压力增加

  • 查询性能下降


十五、总结

DELETE 与 TRUNCATE 虽然都能删除数据。

但它们:

  • 执行机制

  • 日志机制

  • 锁机制

  • 事务行为

  • 性能表现

完全不同。

核心记忆:

命令 特点
DELETE 灵活、安全、慢
TRUNCATE 快速、粗暴、高性能

对于现代数据平台:

  • MySQL 更关注事务与 MVCC

  • PostgreSQL 更强调 WAL 与 MVCC

  • StarRocks 更偏向分区替换与批量处理

因此:

数据库不同。

最佳实践也完全不同。

相关推荐
ggaofeng7 分钟前
自己编写邮件服务器和客户端
数据库
java1234_小锋11 分钟前
【技术专题】Mysql8 数据库 - Mysql8 添加,更新,删除数据
数据库·mysql
PaperData13 分钟前
2015-2024年各省绿色贸易数据
数据库
小羊没烦恼!26 分钟前
系统内部模块(子系统)之间的耦合以及模块(子系统)划分
java·开发语言·前端·数据库·算法·c#
吴建旭 智宅焕1 小时前
智能家居全国交付计价模型的设计与实现:按天包干与交付确定性架构
架构·智能家居
麦壳饼1 小时前
深入探讨:SonnetDB 的文件格式与存储布局
数据库·sonnetdb
Experience-摆渡1 小时前
Agent 持久记忆引擎 Hindsight:分层记忆架构与 Token Budget 机制拆解
架构
for_ever_love__2 小时前
Redis 持久化讲透:RDB、AOF 与混合持久化怎么选
java·数据库·redis·持久化·aof·区别·rdb
l1t2 小时前
测试bicdb 20261007提交的0.2版功能
数据库
星航夜空的帆舟2 小时前
OceanBase源码架构总览
架构·oceanbase