把百万级日志查询从 3 秒优化到 200ms,Claude Code 只用了 2 分钟 AI 负责发现问题人负责判断优先级。一次 Claude Code 辅助性能优化的完整记录附 Prompt 原文和 17 个问题清单。我用 Claude Code 审查了一个有 300 万行数据的日志模块。AI 在两分钟内列出了 17 个性能问题我花了 4 小时筛选出 6 个最值得修改的并实施。最终查询响应从 3 秒降到 200ms。整个过程的核心不是“AI 帮我写了多少代码”而是“AI 帮我找到了问题我来判断哪些该改”。摘要本文记录了使用 Claude Code 对拥有 300 万行数据的日志模块进行性能优化的完整过程。通过精心设计的 Prompt 和项目约束文件AI 在 2 分钟内识别出 17 个性能问题作者从中筛选出 6 个高价值问题并修复。优化后查询响应时间从 2-3 秒降至 200-300 ms性能提升显著。文章分享了 AI 辅助开发的核心经验AI 擅长快速发现问题而人类需要负责判断优先级和决策实施。SEO 摘要本文记录了使用 Claude Code 对 Java 17 Spring Boot 3 MyBatis-Plus MySQL 8 技术栈的 300 万行日志模块进行性能优化的完整实践。AI 在 2 分钟内识别出 17 个性能问题作者按投入产出比筛选 6 个高价值项实施修复最终查询响应从 2-3 秒降至 200-300ms。文章核心经验AI 擅长快速发现问题人类负责判断优先级与决策——Prompt 越具体、约束越明确AI 辅助效果越好。背景我们的系统里有一个日志查询模块数据量接近 300 万条。上线初期体验尚可但随着数据增长翻页操作越来越慢——平均响应时间已达到 2 到 3 秒高峰期甚至超过 5 秒。运营那边开始频繁反馈“页面卡住了”。手头需求排得很紧抽不出半天时间做专项优化。想到 Claude Code 能直接读取项目代码进行分析就决定先让它跑一轮审查看看能否快速定位瓶颈。怎么让 AI 帮我Claude Code 是 Anthropic 推出的命令行 AI 编程助手能直接读取项目代码并给出分析。用过 Copilot 的同学可以把它理解为一个“能看懂整个项目上下文的终端助手”。关键一步是在项目根目录放置一个AGENTS.md文件把技术栈和约束告诉 AI避免它给出不切实际的建议# 项目约束 技术栈: Java 17 Spring Boot 3 MyBatis-Plus MySQL 8 Redis RabbitMQ ORM: MyBatis-Plus 3.5.x不要建议换 Hibernate 构建工具: Maven 日志模块路径: log-service/src/main/java/com/xxx/log/ 约束: - 不要引入新依赖除非有必要且轻量 - SQL 变更需要兼容现有索引 - 线上 MySQL 版本 8.0.35不要用新特性然后启动 Claude Code给它一条指令log-service 请审查 log-service 模块的代码重点关注性能问题。 按 P0必须修/ P1建议修/ P2可选优化分级列出 每个问题给出现象、根因分析、建议修复方案。 最后给出一个优先级排序的总结。这条指令的核心技巧限定范围log-service 模块、限定关注点性能、要求分级P0/P1/P2、要求结构化输出现象 根因 方案。AI 发现了什么大概过了两分钟Claude 返回了17 个问题。我逐条看了一遍整体质量比预期高——大部分问题的根因分析是准确的建议方案也可行。下面是精简后的问题汇总级别数量核心问题P03COUNT(*)无 LIMIT 导致全表扫描排序字段直接拼接 SQL 存在注入风险分页查询未覆盖索引P17异步线程池无界队列字典翻译存在 N1 查询AOP 切面中执行重 IO 操作大事务未拆分等P27日志级别过细、MyBatis prefetch 未调优、部分可合并的 MQ 消息未合并等P0 的问题最致命——COUNT(*)没加 LIMITMySQL 在 300 万行的表上直接全表扫描这就是翻页慢的直接原因。排序字段用String.format拼接 SQL 而非使用参数化查询虽然是内部系统但注入风险依然存在。P1 的问题属于“现在不修迟早要修”的范畴。线程池使用LinkedBlockingQueue默认的 Integer.MAX_VALUE 容量高并发下内存可能被打爆字典翻译在循环里逐条查询10 个字段就是 10 次 SQL。下面是从 AI 发现问题到人工筛选实施的完整决策流程图Claude Code 审查代码输入项目约束 性能审查 PromptAI 输出 17 个问题清单P0/P1/P2 分级人工筛选与决策P0必须修高风险/高收益P1建议修中风险/中收益P2可选优化低风险/低收益筛选标准1. 是否导致核心功能故障2. 性能影响是否显著3. 修复成本是否可控筛选标准1. 投入产出比是否高2. 是否影响长期可维护性3. 当前阶段是否值得投入选出 6 个高价值问题如 COUNT 无 LIMIT、SQL 注入风险等暂缓实施如日志级别调优、prefetch 微调实施与编码约 4 小时含测试验证验证效果响应时间从 3s → 200ms上线观察P99 降至 300ms无内存溢出该流程图展示了从 AI 发现问题到人工筛选、实施、验证的完整闭环突出了分级、筛选标准和最终实施的关键环节。我决定改什么17 个问题不可能一次全改完我按“投入产出比”挑了 6 个影响最大的COUNT 加 LIMIT 1— 分页查询前不再执行COUNT(*)全表扫描改为SELECT COUNT(*) FROM (SELECT 1 FROM table LIMIT 1) t或用 Redis 缓存近似值。仅此一项查询就从 3s 降到 200ms。排序字段白名单校验— 用 MyBatis-Plus 的TableInfoHelper验证排序字段名是否合法彻底消除 SQL 注入风险。字典查询批量化— 把循环里逐条查询字典改为IN批量查询10 次 SQL 合并成 1 次。线程池改有界队列—LinkedBlockingQueue改为ArrayBlockingQueue(200)配合 CallerRunsPolicy 拒绝策略防止内存溢出。重 IO 操作迁到异步线程— AOP 切面里的日志写入和指标上报操作迁到线程池异步执行减少主线程阻塞。MQ ACK 改手动确认 DLQ— 消息消费改为手动 ACK消费失败进入死信队列避免消息丢失又排查不到。实际编码大概花了 4 个小时其中一半时间在测试验证。Claude Code 的建议省去了我最耗时的“定位问题”阶段。效果2-3s → 200-300ms优化前后平均响应时间上线后观察一周主要收益日志查询页面响应时间从 3s 降到 300ms体验上从要等变成秒开高峰期不再出现“页面卡住”的反馈MQ 消费失败的消息进入 DLQ 后可追溯之前丢失的两周日志总算有线索了线程池内存占用稳定在合理区间不再出现过 GC 压力大的告警一点感受这次经历给我的最大感触是AI 在发现问题这个环节确实比人快。17 个问题我自己排查可能需要大半天时间Claude Code 两分钟就列出来了而且准确率不错。但发现问题只是第一步。17 个问题哪些该改、哪些可以延后、改了会不会引入新问题——这些判断还是得由人来做。比如 P2 里的日志级别调优改动小但收益也小在当前阶段不值得投入。回到开头那句话AI 帮我找到了问题我来判断哪些该改。这可能是 AI 辅助开发最真实的工作模式——不是 AI 替你干活而是 AI 帮你看得更远你来决定往哪走。Prompt 越具体AI 看得越清楚。别扔一句“帮我优化代码”就指望好结果——告诉它技术栈、限定范围、明确输出格式效果会好很多。后续监控与调优优化上线不是终点持续监控才能确保效果持久。以下是本次优化后建立的几条监控机制和未来规划慢 SQL 日志分析线上开启了 MySQL 慢查询日志阈值设为 200ms配合pt-query-digest工具每周自动生成慢 SQL 报表并推送到企业微信群。如果发现新的慢查询可以直接丢给 Claude Code 让它先做一轮分析把“人肉排查”变成“AI 先筛一遍”。APM 全链路监控接入了 SkyWalking开源版即可在查询接口和 MQ 消费入口打了自定义埋点重点监控 P99 响应时间、MQ 延迟和线程池队列堆积量。面板上设了告警阈值接口 P99 超过 500ms 或线程池队列积压超过 150 就自动通知——这次优化后这些指标至少帮我们在三次小故障爆发前提前发现了问题。JVM 指标兜底线程池改有界后把ThreadPoolExecutor的getQueue().size()和getActiveCount()以每分钟频率上报到 Prometheus配合 Grafana 面板可视化。同时监控 GC 频率和老年代内存防止线程池调整后连带引发 GC 问题。如果日志模块的数据量继续增长到千万级别当前的单表方案迟早会碰到瓶颈。后续有两个方向可以提前评估读写分离日志查询属于典型的“写多读少但读对延迟敏感”场景把查询打到只读从库可以减轻主库压力配合 MyBatis-Plus 的多数据源配置实现成本不高。分库分表当单表超过 2000 万行时即使索引优化到位复杂度也会上来。初步考虑按日志时间按月分表查询时带上时间范围路由配合 ShardingSphere 做透明分片避免业务代码大改。

本月热点