SQLite3 ANALYZE 与统计维护:sqlite_stat1 / sqlite_stat4、过期症状与批量策略
辨析:标准 SQLite 持久化统计表主要是 sqlite_stat1;sqlite_stat4 在启用
SQLITE_ENABLE_STAT4 编译选项且运行 ANALYZE 时可能出现更细粒度样本。并无广泛意义上的 sqlite_stat3 作为通用第三张系统表——若文档仍写 stat3,多为笔误或其它系统;请以目标发行版的 sqlite_master 与官方 fileformat 文档为准。
1 ANALYZE 在干什么
- 扫描索引 B-Tree 叶节点,采样键分布,写入统计表;
ANALYZE全库;ANALYZE tbl针对相关对象;- 代价:大表上可能耗时与 I/O 显著,应在维护窗口或异步任务跑。
2 sqlite_stat1 结构直觉
存 每个索引的近似摘要,供优化器估计 等值命中行数、范围扫描行数。
可用(谨慎)查询:
SELECT * FROM sqlite_stat1 LIMIT 5;
勿在生产手工乱改行,除非你做科研;正规路径是 重新 ANALYZE。
3 sqlite_stat4(若可用)
提供更丰富样本,利于 高相关列、倾斜分布;二进制构建未开 STAT4 时根本没有这张表。部署文档应写明 是否启用 STAT4。
4 统计过期的典型性能症状
- 同样 SQL,升级数据量后 延迟突然线性变差;
EXPLAIN QUERY PLAN从索引扫描退化为全表扫描;- 批量导入/大批量 DELETE 后 未及时更新。
5 手动更新策略
| 场景 | 建议 |
|---|---|
| 日终批导 | 导入结束 ANALYZE affected_tables |
| 周期任务 | 周/月全库 ANALYZE(视体量) |
| 仅热点表 | ANALYZE hot_table 缩短窗口 |
| 与迁移同发 | schema 变更 + 新索引后 必 ANALYZE |
6 批量维护与自动化
- Shell/cron:
sqlite3 app.db "ANALYZE;" - 失败告警:不要把 ANALYZE 放在「静默脚本」里吞错误。
- PRAGMA optimize(若版本支持):可对需要分析的表做启发式维护——读官方说明再启用。
7 与 VACUUM 的关系
物理紧缩 不自动等价于统计刷新;大维护后常见组合拳:VACUUM(按需)→ ANALYZE。
8 开源仓库实践
- CI:生成测试库后
ANALYZE,让 EQP 测试 稳定。 - Release note:若统计格式变,提醒 用户升级后跑一次 ANALYZE。
9 批量窗口与「analyze 本身变慢」时的拆表策略
大表全库 ANALYZE 若超过允许窗口,可改为 按表排队:先对 JOIN 最多的维度表、再 事实表,每段记录 开始/结束时间与行数快照。若夜间仍不够,考虑 降低写入峰值(合并批处理)或 读副本上 analyze 再决定是否主库执行(谨慎:副本统计不一定等同于主库,仅作近似)。嵌入式设备可把 ANALYZE 绑在 充电+Wi‑Fi 场景,避免用户前台卡顿。
10 与查询计划的反馈闭环
建议在应用侧对 TOP N 慢 SQL 自动归档「上次 ANALYZE 时间戳」;若慢查询在 大批量导入后集中爆发,告警优先级应高于「CPU 飙高」。统计维护本质是 让优化器与数据分布再对齐,而不是运维日历上的装饰品。
11 与「只读副本」统计的边界
若你在工程上维护 主从文件拷贝(非 SQLite 内置复制),在副本上 ANALYZE 得到的统计 仅对副本有效;主库若继续大量写入,把统计文件抄回主库是错误操作。正确做法仍是在 主库低峰 或 业务可接受窗口 执行,或接受 基于主库采样的在线估算(若自研统计中间件)。
总结
统计是 优化器的眼睛;过期则 计划瞎。把 ANALYZE 纳入 数据生命周期(导入后、删改后、索引变更后),比事后集体救火便宜。
更多推荐



所有评论(0)