
一、现象
执行删除后:
sql
DELETE FROM table;
但数据库文件大小没有变化。
二、核心原因
SQLite 使用"页(Page)+ freelist"机制:
1. DELETE 只是逻辑删除
- 数据页不会立即释放
- 进入 freelist
- 文件不会缩小
2. SQLite 设计原因
避免频繁 IO、提升性能、空闲页可复用
3. WAL 模式影响
如果启用 WAL:db-wal 可能占空间、未 checkpoint 不会回收
三、问题检查
sql
PRAGMA freelist_count;
PRAGMA page_count;
PRAGMA journal_mode;
四、解决方案
1. VACUUM(最推荐)
sql
VACUUM;
作用:重建数据库、去除空洞、立即缩小文件
2. WAL checkpoint
sql
PRAGMA wal_checkpoint(FULL);
3. 增量回收
sql
PRAGMA incremental_vacuum;
4. 自动回收
sql
PRAGMA auto_vacuum = INCREMENTAL;
5. 重建数据库(最彻底)
bash
sqlite3 old.db .dump | sqlite3 new.db
五、总结
SQLite 不释放空间本质:
DELETE = 标记删除,不是物理删除