[建议 / Feature] SQLite 数据层重度使用优化:ANALYZE 未运行/无 auto_vacuum/快照查询临时排序/连接调优(825MB 实测)
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 22
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
问题类别 · Category
性能 · Performance(延迟 / 资源占用)
涉及的 Agent 框架 · Agent framework
ZCode Agent(自研)
提交前确认 · Pre-submission checklist
- 已搜索现有 issue,无重复;与 #596(数据保留/清理机制 + 历史懒加载)互补,本条专注 SQLite 引擎与存储层
- 已阅读 CONTRIBUTING.md
使用场景 · Use case
重度使用(日均 10+ 小时长会话 + 多子代理并行),~/.zcode/cli/db/db.sqlite 已 825MB(741 会话 / message 43k 行 / part 170k 行 516.7MB),历史载入 ~10 分钟(详见 #596)。本条是对该库的引擎层实测分析与优化建议。
实测发现(3.11.2,Windows 11,只读探针 + 同机基准)
① 引擎配置现状:
| 项 | 现值 | 评价 |
|---|---|---|
| journal_mode | WAL ✅ | 正确 |
| page_size / page_count | 4096 / 211,527 | 15.9% 的 part 行 >4KB → 走溢出页链(随机 IO) |
| auto_vacuum | 0(NONE) | 删数据永不还空间,须显式 VACUUM(运行时从不执行) |
| sqlite_stat1 | 不存在 | ANALYZE 从未运行,查询计划全靠默认启发式 |
| mmap_size / cache_size | 0 / 2MB | 大库下系统调用式读页 + 页缓存极小 |
| synchronous | 2(FULL) | WAL 下 NORMAL 通常足够且更快 |
| 应用侧 PRAGMA | 仅 journal_mode、foreign_keys 两处(zcode.cjs grep) | 无 busy_timeout/ANALYZE/optimize/缓存调优 |
② 查询计划缺陷实例(快照式查询 SELECT sequence,data FROM part WHERE session_id=? ORDER BY sequence):
SEARCH part USING INDEX part_session_idx (session_id=?)
USE TEMP B-TREE FOR ORDER BY ← 每次快照查询额外排序
现有 part_session_message_sequence_idx(session_id, message_id, sequence) 无法服务纯 ORDER BY sequence;缺 (session_id, sequence) 覆盖索引或查询改序对齐。
③ 同机基准(暖缓存):单会话快照查询 1,519 行/3.0MB 20-23ms;历史列表 top100 1-3ms;825MB 原库 vs 清理到 208MB 的副本几乎无差 → 暖态 SQL 本身不是瓶颈;痛点=冷启动缺页 + WAL checkpoint/杀毒扫描面随库容线性放大 + 应用层对全会话做快照构建(#596 的懒加载建议即治此)。
④ 存储格式:part.data = 裸 JSON 文本。实测压缩:随机 500 行 2.5x、>64KB 大行 2.8x(JSON 混 base64/数据 URL 压缩率有限,但 516.7MB → ~200MB 仍可观)。
建议方案 · Proposal
- 启动/迁移时执行
PRAGMA optimize(或定期 ANALYZE)——一行改动,让计划器拿到统计信息 - 快照查询去排序:补
(session_id, sequence)覆盖索引,或查询 ORDER BY 对齐现有复合索引(消除每次快照的 TEMP B-TREE) - 空间回收:
auto_vacuum = INCREMENTAL(新库)或低频定时 VACUUM 维护任务(与 #596 的保留策略联动——我们按"保留 3 天"清理 538 个会话后 823MB→199MB,integrity ok,级联外键设计很好用) - 连接调优:适度
cache_size(如 -65536)+ 评估mmap_size;评估 WAL 下synchronous=NORMAL;显式busy_timeout(重度子代理并行时读写争抢更平滑) - 评估 page_size=8192:15.9% 行 >4KB,8KB 页可显著减少溢出页链
- 可选:大 part 行(>64KB,实测占 97MB+)透明压缩存储(zstd/zlib,2.8x)或至少数据 URL/base64 内容外置
- 与 #596 的懒加载/保留策略组合:库容有界 + 查询无排序 + 统计信息齐备,冷启动与快照风暴都会显著改善
预期价值 · Expected value
- 快照查询消除每查询排序;统计信息让计划器稳定选对索引
- 库容从无界增长变为有界(825MB→~200MB 量级),冷启动缺页、WAL checkpoint、备份耗时、杀毒扫描面同步下降
- 重度用户历史载入从分钟级回到秒级(配合 #596 懒加载)
你认为的优先级 · Your perceived priority
高 · High
你使用的 ZCode 版本 / 环境 · ZCode version / environment
ZCode Desktop 3.11.2(build 6792,production)/ Windows 11 / GLM Coding Plan
补充材料 · Additional context
实测方法:sqlite3 只读 URI 探针(PRAGMA/分布/EXPLAIN QUERY PLAN)+ 原库与清理副本同机基准 + zlib 压缩采样。数据分布:part 行 p50=216B / p90=6.9KB / p99=44KB / max 874KB;>64KB 大行合计 97.4MB(多为子代理会话的工具结果)。
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by inspecting the SQLite setup and PRAGMA calls in zcode.cjs, then trace the part table schema and snapshot query described in the issue. Compare query plans and benchmarks before and after the selected changes, and verify that migrations or maintenance preserve data integrity and improve the reported storage and startup behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- sqlite
- Domain
- databases, performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100