扫描代码,定位性能关键路径:
mysql-database)当用户提供文件或目录路径时,先执行可复现的静态扫描,再进入人工分析;当用户只粘贴代码片段且没有可访问路径时,跳过工具扫描并明确标注"仅基于片段审查"。
| 扫描档位 | 触发条件 | 扫描范围 | 输出要求 | | - | - | - | - | | 快速扫描 | 单个文件、单个函数、短代码片段 | 当前文件或片段中的循环、I/O、SQL、缓存 | 输出命中位置和疑似反模式 | | 深度扫描 | 目录、模块、项目级性能排查 | 入口、循环、数据库访问、网络调用、缓存、异步任务 | 输出扫描摘要、热点候选和后续验证路径 |
推荐扫描模式:
| 扫描项 | 参考模式 | 风险 |
| - | - | - |
| 循环内数据库调用 | for / foreach / while 附近出现 query / select / find / where | N+1 查询 |
| 循环内外部请求 | 循环附近出现 fetch / axios / requests / http / RestTemplate | N+1 API 调用 |
| 同步阻塞 I/O | readFileSync / writeFileSync / 同步文件读写 / 高并发路径阻塞调用 | 阻塞 I/O |
| 无上限数据拉取 | .all() / findAll() / SELECT * / 无 LIMIT 的列表查询 | 内存和响应时间失控 |
| 缓存无界增长 | 全局 Map/dict/Object/静态集合持续写入且无 TTL/容量限制 | 内存泄漏 |
| 索引失效 | DATE(column) / LIKE '%xxx' / 字段隐式类型转换 | 慢查询 |
扫描结果只能作为嫌疑点;交付结论必须继续通过 benchmark、profile、EXPLAIN、日志或人工复核验证。
根据问题规模选择分析层级,避免简单问题过度分析,也避免复杂问题只给浅层建议:
| 层级 | 触发条件 | 分析内容 | 输出形态 | | - | - | - | - | | L0 轻量分析 | 单条 SQL、单个函数、少于 30 行的小片段 | 直接复杂度、明显 I/O、单点风险 | 简短结论 + 1 到 3 个建议 | | L1 标准分析 | 多函数、循环 + DB、常规重构、30 到 200 行代码 | 复杂度、I/O、边界条件、数据量影响 | 热点表格 + 修复方案 | | L2 深度分析 | 多文件、架构级优化、线上瓶颈、超过 200 行或涉及并发 | L1 全部 + 并发、内存、缓存、扩展性、回滚风险 | 分阶段诊断和验证计划 |
| 反模式 | 典型信号 | 严重度 | 最小修复方向 | | - | - | - | - | | N+1 查询 | 循环内数据库查询或外部 API 调用 | 严重 | 批量查询、预加载、JOIN、聚合、一次性拉取后内存分组 | | 同步阻塞 I/O | 高并发请求路径内同步文件、网络或重 CPU 操作 | 严重 | 异步化、后台任务、连接池、队列、流式处理 | | 内存泄漏风险 | 无界缓存、监听器未清理、静态集合持续增长 | 高 | TTL、容量限制、LRU、生命周期清理 | | 无上限数据拉取 | 列表查询无分页、无最大 limit、全表拉取 | 高 | 强制分页、游标、批处理、最大 page size |
识别反模式后,按问题性质选择策略;没有实测基线时只能描述"预期收益"或"假设收益",不得声称已提升。
| 策略 | 适用场景 | 风险控制 | | - | - | - | | 缓存优先 | 高频读取、变更不频繁、可接受短暂不一致 | 明确 TTL、失效时机、穿透/击穿/雪崩防护 | | 异步处理 | 耗时超过用户等待阈值的非核心副作用 | 明确幂等、重试、死信、失败告警和最终一致性 | | 索引优化 | WHERE/JOIN/ORDER BY 慢查询 | 必须提供 EXPLAIN,评估写入成本和回滚方案 |
优化建议输出需包含:问题位置、当前路径、方案、预期收益依据、验证命令、回滚方式。
按语言和场景选择:
| 语言 | 工具 | 适用场景 |
| - | - | - |
| Python | cProfile / timeit / pytest-benchmark | 函数级耗时、逐行热点 |
| Node.js | console.time / benchmark.js / clinic | 火焰图、事件循环延迟 |
| Go | go test -bench / pprof | CPU/内存 profile |
| Java | JMH | 微基准测试 |
| PHP | microtime() / Xdebug profiler | 函数耗时 |
首选策略:若项目已有测试框架,优先用其内置 benchmark(如 pytest-benchmark、go test -bench),降低接入成本。
tracemalloc / memory_profiler / process.memory_info())对超出阈值的热点逐条分析:
| 指标 | 优化前 | 优化后 | 提升 | | - | - | - | - | | 耗时 | X ms | Y ms | Z% | | 内存 | X MB | Y MB | Z% | | 调用次数 | X | Y | Z% |
性能基准测试完成后,将以下内容沉淀到项目记忆(参见 project-memory-management.md):
## 性能基准测试报告
**目标代码**:[函数/模块名]
**测试环境**:[OS / CPU / 内存 / Python 版本]
## 基准数据
| 指标 | 中位数 | P95 | P99 | 峰值内存 |
|------|--------|-----|-----|---------|
| [指标1] | [值] | [值] | [值] | [值] |
## 热点分析
| 位置 | 耗时占比 | 根因 | 优化建议 | 预期收益 |
|------|---------|------|---------|---------|
| [文件:行号] | X% | [原因] | [方案] | ~Y% |
## 优化前后对比(如有基线)
| 指标 | 优化前 | 优化后 | 提升 |
|------|--------|--------|------|
## 测试脚本
```[语言]
[可复现的 benchmark 代码]
| 步骤 | 失败条件 | 回退目标 | 最大重试 | 不可恢复时升级路径 |
|---|---|---|---|---|
| 第一步:识别触发面 | 代码量过大无法定位关键路径 | 按函数分批,标注"仅部分路径" | 1 | 缩小范围到用户指定的入口函数 |
| 第二步:选择优化策略 | 无实测基线或策略不明 | 先跑基线,标注"预期收益/假设收益" | 1 | 输出候选策略与权衡,由用户决策 |
| 第三步:选用测量工具 | 工具不可用或安装失败 | 降级到语言内置 time 打点 | 1 | 输出手动计时方案,标注精度受限 |
| 第四步:执行测量 | 环境差异导致数据波动 > 20% | 增加采样次数到 7 次,输出方差 | 2 | 标注"环境不稳定",以区间范围呈现 |
| 第五步:生成瓶颈报告 | 热点根因无法在静态分析中确定 | 输出热点位置 + 耗时占比,标注"根因待确认" | 1 | 建议用户补充 profiler 火焰图 |
| 第六步:优化前后对比 | 无优化前基线 | 仅输出当前基准,标注"无基线对比" | — | 正常输出 |
| 第七步:记录到项目记忆 | 项目记忆系统不可用 | 输出性能基线数据到本地文件 | 1 | 标注"基线未沉淀",提示用户手动保存 |
mysql-database 做 EXPLAIN / 索引分析