【架构】-- 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 区别深度解析

一、前言

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

很多开发人员认为:

  • 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 更偏向分区替换与批量处理

因此:

数据库不同。

最佳实践也完全不同。

相关推荐
睡不醒男孩0308231 小时前
第二篇:深入探索开源数据库高可用:构建基于CLup的PostgreSQL生产级高可用与读写分离架构
数据库·postgresql·开源·clup
love530love3 小时前
LiveTalking 数字人项目 Windows 部署完全指南(EPGF 架构)
人工智能·windows·python·架构·livetalking·epgf
Leaton Lee3 小时前
Spring Boot分层架构详解:从Controller到Service再到Mapper的完整流程
java·spring boot·后端·架构
Micro麦可乐3 小时前
Spring Boot 实战:从零设计一个短链系统(含完整代码与数据库设计)
数据库·spring boot·后端·哈希算法·雪花算法·短链系统
码农阿豪3 小时前
从零到一:Spring Boot快速接入金仓数据库实战
数据库·spring boot·后端
鼎讯信通4 小时前
风电光缆运维提质增效:G-4000A 光缆故障追踪仪破解风场巡检难题
运维·网络·数据库
三十..4 小时前
MySQL 从入门到高可用架构实战精要
运维·数据库·mysql
凌云拓界4 小时前
文件管理:让AI安全操作你的电脑 ——CogitoAgent开发实战(三)
javascript·人工智能·架构·开源·node.js
cfm_29145 小时前
Redis五大基本数据结构底层了解
数据结构·数据库·redis