使用 AI 修改真实项目时,有一种问题很容易被忽略:
功能已经改对了,测试也能通过,但接口却越来越慢。
比如原来一个接口响应只需要:
200ms
AI修改后功能完全正常,却变成:
800ms
1.5s
甚至更慢
代码没有明显报错,返回结果也正确。
真正发生的问题可能是:
功能正确了,但执行成本被悄悄放大了。
这类问题在数据量小时不明显,到了真实业务环境才容易暴露。
一、结果正确,不代表实现方式没有问题
假设需要查询100个用户对应的订单。
原来的代码可能是:
一次查询100个用户
+
一次批量查询订单
总共只需要少量数据库请求。
但AI重构后可能变成:
查询100个用户
↓
循环用户
↓
每个用户单独查询订单
于是数据库请求数量从几次变成:
1 + 100
功能完全正确。
只是接口速度明显下降。
这就是典型的:
N+1查询问题。
二、为什么AI容易产生N+1查询?
因为单看局部代码,这种写法非常自然:
for (const user of users) {
const orders = await getOrders(user.id)
}
每一行逻辑都没有问题。
问题出在:
它会执行多少次。
如果只有3个用户,几乎感觉不到差别。
如果有:
100
1000
10000
个对象,数据库访问次数就会迅速增加。
所以检查AI代码时,除了问:
这段逻辑对不对?
还应该问:
这段逻辑会执行多少次?
三、重复请求也会制造隐藏性能问题
类似问题不只发生在数据库。
例如一个页面需要用户信息。
AI修改以后,三个组件分别调用:
getUser()
最终可能产生:
组件A → 请求一次
组件B → 请求一次
组件C → 请求一次
明明是同一份数据,却请求了三遍。
页面仍然可以正常显示。
但:
-
网络请求增加;
-
服务端压力增加;
-
页面等待时间增加。
这种问题如果只检查最终页面,很容易被忽略。
四、重复计算同样会拖慢接口
例如代码里需要计算:
用户权限
原本只算一次。
AI重构后可能在多个判断里重复执行:
checkPermission()
checkPermission()
checkPermission()
如果这个函数内部还包含:
-
数据库查询;
-
文件读取;
-
复杂计算;
成本就会进一步放大。
所以某些性能问题看起来只是:
多调用了几次函数。
实际上背后可能多执行了很多操作。
五、为什么测试通过也发现不了?
普通功能测试更关注:
输入
↓
输出是否正确
例如:
查询用户接口是否返回20条数据?
只要结果正确,测试就可能通过。
但测试并没有检查:
执行了多少条SQL?
调用了多少次接口?
花了多少时间?
所以会出现:
行为正确,但性能已经退化。
这也是为什么性能问题不能完全依赖普通单元测试发现。
六、小数据尤其容易掩盖问题
开发环境可能只有:
10条测试数据
即使发生N+1查询:
1 + 10
次SQL,也不会特别慢。
但生产环境可能一次处理:
1000条数据
查询次数就可能变成:
1 + 1000
这时候问题才突然明显。
所以AI修改涉及:
-
列表;
-
批处理;
-
循环;
-
关联查询;
时,最好特别检查:
数据量扩大以后成本会不会线性甚至更快增长。
七、怎么发现N+1和重复调用?
一个简单办法是看日志。
例如开启SQL日志后观察:
SELECT users...
SELECT orders WHERE user_id = 1
SELECT orders WHERE user_id = 2
SELECT orders WHERE user_id = 3
...
如果大量相似SQL不断出现,通常就值得检查。
同样也可以记录:
API调用次数
函数执行次数
接口耗时
数据库查询次数
有时候只需要比较:
修改前和修改后
就能很快发现问题。
八、批量查询通常比循环查询更合理
例如:
100个userId
与其循环执行:
getOrders(userId)
100次。
更合理的方案可能是一次性查询:
getOrdersByUserIds(userIds)
再在内存中按照用户进行分组。
这样数据库交互次数会明显减少。
当然具体实现要根据项目情况决定。
关键不是机械地“全部改成批量”。
而是先确认:
有没有重复访问同一种资源。
九、缓存也可能被AI无意绕过
有些项目原本已经有:
缓存
↓
数据库
AI为了快速完成新功能,可能直接调用底层数据库方法。
结果:
原来的缓存层没有走。
功能仍然完全正确。
但数据库压力突然增加。
所以AI新增调用路径时,还应该检查:
项目是不是已经有统一的数据访问入口?
如果有,最好优先复用原来的调用方式,而不是重新绕一条路径。
十、可以让AI主动做一次“性能影响检查”
完成代码修改以后,可以继续要求:
请检查本次修改可能带来的性能变化:
1. 是否在循环中增加数据库查询;
2. 是否重复调用同一个API;
3. 是否重复执行高成本函数;
4. 是否绕过已有缓存;
5. 数据量扩大100倍后是否会明显变慢;
6. 哪些地方适合改成批量处理。
这一步并不要求AI马上优化。
先找出潜在问题,再决定是否需要调整。
十一、一个实用的检查顺序
如果AI改完代码以后功能正常,但接口明显变慢,可以依次检查:
第一步:比较修改前后耗时。
确认性能下降是不是本次修改引起。
第二步:看数据库查询次数。
有没有N+1。
第三步:看网络请求次数。
有没有重复请求。
第四步:检查循环内部。
是否存在高成本操作。
第五步:检查缓存路径。
有没有绕开原有缓存。
第六步:用更大数据量重新测试。
确认性能问题是否随数据增长被放大。
最后
AI改完代码后功能正常,接口却越来越慢,本质上说明:
“代码正确”只解决了第一层问题。
真实项目还需要继续关注:
这段代码用了多少数据库查询、多少网络请求、多少重复计算,以及数据量增长以后成本会不会被放大。
尤其是:
循环
+
数据库
+
API
+
异步任务
同时出现时,更应该检查执行次数。
AI很容易写出局部完全正确的代码。
但工程质量还需要进一步确认:
它是不是用合理的成本完成了这件事。
持续更新 Codex、Claude Code 与大模型开发实战内容,更多深度内容和稳定订阅渠道欢迎搜索关注「孤狼GPT」。

469

被折叠的 条评论
为什么被折叠?



