辨析:标准 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 纳入 数据生命周期(导入后、删改后、索引变更后),比事后集体救火便宜。

更多推荐