在 SQLite 中,VACUUM 是一个 数据库维护命令,用于:
重建整个数据库文件,释放碎片空间,优化性能,重置自增 ID,压缩文件体积。
一、VACUUM 的作用
| 功能 | 说明 |
|---|---|
| 清理碎片 | 删除/更新操作会留下“空洞”,VACUUM 重新整理 |
| 压缩文件 | 减小 .db 文件大小 |
重置 freelist | 释放未使用页面 |
| 重建索引 | 所有索引被重建(更紧凑) |
重置 sqlite_sequence | 可配合 INCREMENTAL_PRAGMA 重置自增 ID |
二、基本语法
VACUUM;
默认 全量重建 数据库
三、进阶用法
1. VACUUM INTO 'filename.db' (SQLite 3.27.0+)
将清理后的数据库 另存为新文件,原文件不变。
VACUUM INTO 'backup_clean.db';
安全!不影响原数据库
2. INCREMENTAL VACUUM (增量模式,推荐生产)
避免一次性锁库,适合 大数据库。
步骤:
-- 1. 启用增量模式
PRAGMA incremental_vacuum;
-- 2. 控制每次清理页面数(例如 100 页)
PRAGMA incremental_vacuum(100);
-- 3. 重复执行直到完成
每次只清理部分碎片,不锁库
3. auto_vacuum —— 自动清理(推荐开启)
| 模式 | 说明 |
|---|---|
NONE(默认) | 不自动清理,需手动 VACUUM |
FULL | 每次事务结束自动清理碎片 |
INCREMENTAL | 支持手动增量清理 |
开启方式:
-- 建库时设置(推荐)
PRAGMA auto_vacuum = FULL;
-- 或
PRAGMA auto_vacuum = INCREMENTAL;
注意:建库后无法更改!需重建数据库
四、什么时候执行 VACUUM?
| 场景 | 是否需要 |
|---|---|
频繁 DELETE / UPDATE | ✅ |
| 数据库文件明显变大 | ✅ |
| 准备发布/备份 | ✅ |
| 性能下降(查询变慢) | ✅ |
| 日常小表 | ⚠️ 可选 |
五、完整操作示例
示例 1:手动全量清理
-- 1. 备份(安全第一)
-- cp app.db app_backup.db
-- 2. 执行清理
VACUUM;
-- 3. 查看效果
PRAGMA page_count; -- 页面数减少
PRAGMA freelist_count; -- 空闲页面归零
示例 2:增量清理(大表推荐)
-- 1. 确保支持 incremental
PRAGMA auto_vacuum = INCREMENTAL;
-- 2. 分批清理(每批 500 页)
PRAGMA incremental_vacuum(500);
-- 3. 循环执行直到返回 0
-- 可写脚本自动化
Python 自动化脚本
import sqlite3
conn = sqlite3.connect('big.db')
cur = conn.cursor()
while True:
cur.execute("PRAGMA incremental_vacuum(500)")
pages = cur.fetchone()[0]
if pages == 0:
break
print(f"Cleaned {pages} pages...")
print("VACUUM completed!")
conn.close()
示例 3:重置自增 ID + 清理
-- 1. 清空表
DELETE FROM users;
-- 2. 重置自增计数
DELETE FROM sqlite_sequence WHERE name = 'users';
-- 3. 清理碎片
VACUUM;
下次插入从
1开始,文件变小
六、查看数据库状态
-- 页面总数
PRAGMA page_count;
-- 空闲页面数(碎片)
PRAGMA freelist_count;
-- 页面大小
PRAGMA page_size;
-- 估算文件大小
SELECT page_count * page_size / 1024.0 / 1024.0 AS size_mb;
-- auto_vacuum 状态
PRAGMA auto_vacuum;
七、VACUUM 的代价
| 项目 | 影响 |
|---|---|
| 锁库 | 全量 VACUUM 会 独占数据库 |
| 时间 | 与数据库大小成正比 |
| 磁盘空间 | 临时需要 2倍空间 |
| 事务回滚 | 中断后自动回滚 |
生产环境建议:
- 备份 →
VACUUM INTO→ 替换- 或使用
INCREMENTAL分批执行
八、最佳实践建议
| 建议 | 操作 |
|---|---|
| 建库就开启 | PRAGMA auto_vacuum = FULL; |
| 定期维护 | 每月/删除量大时执行 VACUUM |
| 大库用增量 | PRAGMA incremental_vacuum(N) |
| 发布前清理 | VACUUM INTO 'release.db' |
| 备份后压缩 | VACUUM INTO 'backup_2025.db' |
九、图形化工具支持
| 工具 | VACUUM 操作 |
|---|---|
| DB Browser for SQLite | Database → Vacuum |
| DBeaver | 右键数据库 → Vacuum |
| SQLiteStudio | Tools → Vacuum |
总结:VACUUM 快速参考
| 命令 | 用途 |
|---|---|
VACUUM; | 全量重建,锁库 |
VACUUM INTO 'new.db'; | 安全另存 |
PRAGMA auto_vacuum = FULL; | 自动清理(建库时设) |
PRAGMA incremental_vacuum(100); | 分批清理,不锁库 |
PRAGMA page_count; | 查看压缩效果 |
快速诊断脚本
-- 一键查看是否需要 VACUUM
SELECT
'File size (MB)' AS metric,
page_count * page_size / 1024.0 / 1024.0 AS value
FROM pragma_page_count(), pragma_page_size()
UNION ALL
SELECT 'Free pages', freelist_count FROM pragma_freelist_count()
UNION ALL
SELECT 'Auto vacuum', auto_vacuum FROM pragma_auto_vacuum();
Free pages> 1000?→ 该VACUUM了!
需要我帮你:
- 生成自动
VACUUM脚本? - 分析你的
.db文件是否需要清理? - 安全执行
VACUUM INTO并替换?
把你的数据库大小或 PRAGMA page_count 结果发我!