perf: reduce homepage database hot paths and chunk large key queries#287
perf: reduce homepage database hot paths and chunk large key queries#287mozi1924 wants to merge 4 commits into
Conversation
KilimiaoSix
left a comment
There was a problem hiding this comment.
本次 code review 不通过。主要问题是:PR 的核心热点优化没有完整接入服务层,部分新统计查询在大 key 集合下仍会重复扫描,并且新增 SQL/IN-list 逻辑存在明显重复,后续容易产生统计口径漂移。请优先修复下方阻塞项后再请求复审。
| /// | ||
| /// # 返回 | ||
| /// 返回函数执行结果 | ||
| pub fn list_api_key_ids_for_user(&self, user_id: &str) -> Result<Vec<String>> { |
There was a problem hiding this comment.
这里新增了按 owner_kind + owner_user_id 查询 key id 的索引路径,但服务层实际使用的 crate::list_api_key_ids_for_user 仍然调用 storage.list_api_key_owners() 拉全量 owner 后在 Rust 里过滤。因此成员 Dashboard、startup snapshot、API Key 页面仍会走旧热点路径,PR 的主要优化没有真正生效。建议把服务层 helper 改为调用这个新的 storage 方法,并补一个覆盖非 admin 路径的测试。
| return Ok(Vec::new()); | ||
| } | ||
| let mut items = Vec::new(); | ||
| for chunk in normalized_key_ids.chunks(SQLITE_IN_CLAUSE_BATCH_SIZE) { |
There was a problem hiding this comment.
这里按 900 个 key 分 chunk 后,每个 chunk 都会重新执行一次包含 request_token_stats UNION ALL request_token_stat_rollups 的统计查询。用户/组织 key 数超过 900 时,成员用量页会按 chunk 数重复扫描 stats/rollup,性能开销会被放大。建议考虑临时表、VALUES CTE,或把 key 集合作为一次 join/filter 输入,避免每个 chunk 重新扫聚合来源。
| let Some(clause) = key_id_filter_clause("key_id", key_ids, &mut params) else { | ||
| return Ok(Vec::new()); | ||
| }; | ||
| let mut stmt = self.conn.prepare(&format!( |
There was a problem hiding this comment.
过滤版 by-key 查询基本复制了非过滤版统计 SQL;同一个文件里 by-model、by-key-and-model 也有类似的过滤/非过滤双份 SQL。后续如果调整 token total 计算、rollup 纳入规则、model 归一化、字段或排序,很容易只改一处,导致成员视角和管理员/全局统计口径漂移。建议抽出共享 query builder/row mapper,只把 key filter 作为可选条件拼进去。
| Ok(out) | ||
| } | ||
|
|
||
| fn normalize_key_ids(key_ids: &[String]) -> Vec<String> { |
There was a problem hiding this comment.
normalize_key_ids 以及 IN (?, ...) 占位符构造逻辑在 api_keys.rs、api_key_quota_limits.rs、request_token_stats.rs 中重复出现。后续调整 batch size、空列表语义或 key id 规范化时需要改多份代码,容易产生不一致。建议提取一个 storage 层共享 helper,统一处理 normalize/chunk/placeholder 参数构造。
|
已根据 review 反馈补充修复:
验证已通过: |
变更摘要
IN (...)key 列表查询做分批,规避 SQLite host parameter 上限,提升大 key 集合场景的稳定性。改动范围
主要文件
crates/core/src/storage/request_token_stats.rscrates/core/src/storage/api_keys.rscrates/core/src/storage/api_key_quota_limits.rscrates/service/src/account/account_list.rscrates/service/src/apikey/apikey_usage_stats.rscrates/core/src/storage/tests/request_token_stats_tests.rscrates/core/src/storage/tests/api_keys_tests.rs验证
cargo check -p codexmanager-core -p codexmanager-servicecargo test -p codexmanager-core summaries_for_large_key_lists_are_chunked -- --nocapturecargo test -p codexmanager-core large_key_sets_are_chunked_for_api_key_and_quota_queries -- --nocapturecargo test -p codexmanager-service --libpnpm -C apps run buildpnpm -C apps run test:runtime已执行的实际验证:
未执行的验证与原因:
风险与影响面
备注