在 SQLite 中,删除记录或表后,并不会立即释放磁盘空间。VACUUM 命令是 SQLite 提供的官方机制,用于整理数据库文件结构并释放未使用的空间。它相当于数据库的“磁盘碎片整理工具”,对于嵌入式应用、日志系统、移动端数据库尤为重要。


📚 目录

  1. 什么是 SQLite VACUUM?
  2. 为什么要执行 VACUUM?
  3. VACUUM 的工作机制
  4. VACUUM 与自动回收机制的区别
  5. VACUUM 的使用方法与示例
  6. VACUUM FULL vs INCREMENTAL
  7. 使用注意事项
  8. 出站参考与站内推荐阅读
  9. 参考资料

1. 什么是 SQLite VACUUM?

VACUUM 是一个 SQLite 命令,用于重建数据库文件,以移除内部未使用的空间。该过程会:

  • 释放因 DELETE/UPDATE/REINDEX 等操作而留下的“空洞页”
  • 整理数据页顺序,提升读取效率
  • 缩小数据库文件大小
  • 重建数据库并导入原始数据

2. 为什么要执行 VACUUM?

以下场景建议定期执行 VACUUM

  • 大量删除数据后数据库未缩小
  • 数据库文件快速膨胀
  • 有频繁的事务或日志性操作
  • 要将数据库压缩后备份或迁移

3. VACUUM 的工作机制

执行 VACUUM 会执行以下步骤:

  1. 创建一个临时数据库文件
  2. 将当前数据库的表结构和数据复制过去(仅复制有效内容)
  3. 删除原数据库文件
  4. 重命名临时文件为原始文件名

该过程会重建整个数据库文件,因此会释放所有空闲页,并重新组织表/索引结构。


4. VACUUM 与自动空间管理机制的区别

方法是否自动效果特点
VACUUM全面整理需要手动执行,效率高但阻塞
auto_vacuum渐进式空间可自动回收,但复杂度高
incremental_vacuum手动推进可逐页回收,不阻塞,但需维护页管理

推荐做法:

  • 正常项目用 VACUUM
  • 嵌入式场景考虑 auto_vacuum = FULLINCREMENTAL

设置示例:

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. 📚 参考资料

  1. SQLite 官方文档:https://sqlite.org/lang_vacuum.html
  2. SQLite 源码文件:vacuum.c
  3. 《SQLite 权威指南》(O’Reilly)
  4. Hacker News 对 VACUUM 性能问题的社区讨论
  5. Stack Overflow 社区经验帖与实战案例

✅ 下一篇将带你进入《SQLite 日期 & 时间:时间函数、格式与转换实践》,系统梳理 SQLite 中的时间处理方法,包括 date()datetime()strftime()、时区控制与格式转换技巧。如果你准备好了,我马上继续。