在 SQLite 中,删除记录或表后,并不会立即释放磁盘空间。VACUUM
命令是 SQLite 提供的官方机制,用于整理数据库文件结构并释放未使用的空间。它相当于数据库的“磁盘碎片整理工具”,对于嵌入式应用、日志系统、移动端数据库尤为重要。
📚 目录
- 什么是 SQLite VACUUM?
- 为什么要执行 VACUUM?
- VACUUM 的工作机制
- VACUUM 与自动回收机制的区别
- VACUUM 的使用方法与示例
- VACUUM FULL vs INCREMENTAL
- 使用注意事项
- 出站参考与站内推荐阅读
- 参考资料
1. 什么是 SQLite VACUUM?
VACUUM
是一个 SQLite 命令,用于重建数据库文件,以移除内部未使用的空间。该过程会:
- 释放因 DELETE/UPDATE/REINDEX 等操作而留下的“空洞页”
- 整理数据页顺序,提升读取效率
- 缩小数据库文件大小
- 重建数据库并导入原始数据
2. 为什么要执行 VACUUM?
以下场景建议定期执行 VACUUM
:
- 大量删除数据后数据库未缩小
- 数据库文件快速膨胀
- 有频繁的事务或日志性操作
- 要将数据库压缩后备份或迁移
3. VACUUM 的工作机制
执行 VACUUM
会执行以下步骤:
- 创建一个临时数据库文件
- 将当前数据库的表结构和数据复制过去(仅复制有效内容)
- 删除原数据库文件
- 重命名临时文件为原始文件名
该过程会重建整个数据库文件,因此会释放所有空闲页,并重新组织表/索引结构。
4. VACUUM 与自动空间管理机制的区别
方法 | 是否自动 | 效果 | 特点 |
---|---|---|---|
VACUUM | 否 | 全面整理 | 需要手动执行,效率高但阻塞 |
auto_vacuum | 是 | 渐进式 | 空间可自动回收,但复杂度高 |
incremental_vacuum | 是 | 手动推进 | 可逐页回收,不阻塞,但需维护页管理 |
推荐做法:
- 正常项目用
VACUUM
- 嵌入式场景考虑
auto_vacuum = FULL
或INCREMENTAL
设置示例:
PRAGMA auto_vacuum = FULL;
PRAGMA incremental_vacuum(10);
5. VACUUM 的使用方法与示例
最基本用法:
VACUUM;
指定目标文件:
VACUUM INTO 'compacted.db';
这个命令会将优化后的数据库导出为 compacted.db
,不影响原文件。
6. VACUUM FULL vs INCREMENTAL
SQLite 不存在 VACUUM FULL
关键词(那是 PostgreSQL 术语),但我们可以使用以下方式理解:
类型 | 相当于 |
---|---|
VACUUM | 全量瘦身 |
auto_vacuum = FULL | 自动回收全部页 |
auto_vacuum = INCREMENTAL | 手动触发回收部分页 |
要启用 INCREMENTAL
模式:
PRAGMA auto_vacuum = INCREMENTAL;
VACUUM; -- 设置后首次执行生效
PRAGMA incremental_vacuum(5); -- 回收 5 页
7. 使用注意事项
VACUUM
会锁定整个数据库(读写均阻塞)- 不可在事务中执行
- 必须有足够磁盘空间临时生成新数据库
- 不建议频繁执行(建议根据数据操作频率定期处理)
8. 🔗 出站参考与站内推荐阅读
外部资源
推荐阅读(站内):
9. 📚 参考资料
- SQLite 官方文档:https://sqlite.org/lang_vacuum.html
- SQLite 源码文件:
vacuum.c
- 《SQLite 权威指南》(O’Reilly)
- Hacker News 对 VACUUM 性能问题的社区讨论
- Stack Overflow 社区经验帖与实战案例
✅ 下一篇将带你进入《SQLite 日期 & 时间:时间函数、格式与转换实践》,系统梳理 SQLite 中的时间处理方法,包括 date()
、datetime()
、strftime()
、时区控制与格式转换技巧。如果你准备好了,我马上继续。
发表回复