开发者分享让 AI 承包 95% 代码的真实体验。从工具选型、流程设计到最终落地的完整案例。
用 AI 写几乎所有代码的感觉还是有点奇怪——但我决定在这个新项目上认真尝试一次。先做点背景介绍:我在这里的项目创意快用完了,所以我问了 AI 要一个列表,然后挑了一个叫"数据库性能测试"的项目。目标是对关系数据库运行性能测试。我在大约两天内完成了这个项目,在这篇文章中我想分享我的诚实印象——既包括技术层面,也包括 AI 辅助工作流本身。
我认为这是开始任何项目前第一个需要问的问题。碰巧的是,我目前在一个项目中,数据性能是一个关键系统问题——这让我思考:直接对关系数据库运行性能测试会是什么样子?
从 QA 的角度来看,性能不仅是 API 如何连接到数据库的问题。它也关乎查询如何被编写,以及所选数据库如何处理查询并发,特别是在同步系统中。一个慢的端点不一定总是一个真正慢的端点——有时它只是背后隐藏着一个慢查询。这就是驱使我从这里开始的原因。
对于这个项目,我们有四个不同的测试场景:
N+1 是应用程序访问数据库时的一个经典性能问题——特别是使用 Entity Framework、SQLAlchemy 或 Sequelize 等 ORM 的系统。这个名称准确描述了发生的事情:与其说是一个优化的查询,不如说应用最后会运行 1 个初始查询 + N 个额外查询。
考虑一个电商系统,列出 20 个订单并显示每个订单所属用户的邮箱。幼稚的方法会是:
SELECT id, user_id FROM orders LIMIT :n;
SELECT email FROM users WHERE id = :uid;
第一个查询获取订单。第二个查询随后运行 20 次——每个订单一次。那就是你的 N+1。大规模的后果包括延迟倍增、缓存污染,以及用户响应时间不可预测。
这也会在并发场景中出现。两个线程同时获取用户数据,各自触发自己的查询级联,可以迅速以难以追踪的方式增加数据库负载。
想象两个事务同时发生:
UPDATE orders SET status = 'pending' WHERE id = 1;
UPDATE orders SET status = 'paid' WHERE id = 2;
Transaction B(同时运行,顺序相反):
UPDATE orders SET status = 'paid' WHERE id = 2;
UPDATE orders SET status = 'pending' WHERE id = 1;
每个事务都持有另一个需要的锁。数据库检测到这个循环并通过回滚其中一个事务来解决——但该回滚是有代价的。大规模下,这种竞争会导致明显的延迟峰值,在最坏的情况下,锁定应用的部分。死锁测试的目标不仅仅是确认死锁可以发生,而是测量数据库如何恢复以及时序影响是什么样的。
这个场景关注测量 schema 变化——索引创建、迁移、表修改——对查询执行计划和时序的影响。它在迁移前后捕获 EXPLAIN ANALYZE 输出,然后对结果进行 diff。
这特别有用于:
在合并前验证优化确实改进了性能
记录 schema 版本及其性能特征随时间的变化
在定期运行作为基准时支持生产调查
慢查询测试充当一个延迟门槛——一组关键查询必须保持在定义的阈值下(在 config.py 中配置为 SLOW_QUERY_THRESHOLD_MS)。如果这些查询中的任何一个在 CI 中超过阈值,管道就会失败。
把它想象成你最重要的数据库操作的性能预算。在这个项目中,五个关键查询被监控。以下是低容量基准运行的结果:
所有三个都舒适地通过了阈值。但这里的价值不仅仅是绿灯——它是拥有一个历史基准。下一次有人添加过滤器、改变连接或删除索引时,你会立即知道这些数字是否移动。
以下是项目的组织方式:
.
├── config.py # DB_URL and SLOW_QUERY_THRESHOLD_MS
├── conftest.py # pytest fixtures: engine, instrumented_engine
├── pyproject.toml # pytest config and markers
├── requirements.txt
├── analysis/
│ ├── n_plus_one_detector.py # N+1 detection and simulation
│ ├── deadlock_simulator.py # Concurrent deadlock demo
│ └── explain_analyzer.py # EXPLAIN plan capture and diff
├── benchmarks/
│ ├── queries/ # Raw .sql files (12 queries)
│ ├── scenarios/
│ │ └── run_benchmark.py # Volume benchmark runner
│ ├── test_n_plus_one.py # N+1 detection tests
│ ├── test_deadlock.py # Deadlock tests
│ ├── test_explain.py # EXPLAIN ANALYZE plan tests
│ └── test_slow_queries.py # Latency threshold gate (5 critical queries)
├── data/
│ ├── seed.py
│ └── distributions.json
├── migrations/
│ ├── baseline/
│ │ └── 001_initial_schema.sql
│ └── v2_add_indexes/
│ └── 002_add_indexes.sql # Sample migration for regression demo
├── reports/
│ ├── query_regression_report.py # Delta reporter (also exports to Grafana)
│ ├── export_metrics.py # Writes results to benchmark_results table
│ ├── output/ # Timestamped benchmark JSON results
│ └── plans/ # Saved EXPLAIN plans
├── scripts/
│ └── setup_schema.py # Apply migration + snapshot schema
├── .github/
│ └── workflows/
│ └── performance-tests.yml # CI: schema → seed → pytest
└── docker/
├── docker-compose.yml # PostgreSQL + Grafana
├── init.sql
└── grafana/
├── provisioning/
└── dashboards/benchmark.json # Auto-provisioned dashboard
这个结构中有几个值得强调的地方:
analysis/ 被设计为可以独立运行。每个模块——N+1 检测、死锁模拟、EXPLAIN 分析——都可以单独执行。你不必每次都运行完整套件。这在实践中很重要:有些时候你只关心迁移后的回归跟踪,同时运行死锁模拟只是噪声。
explain_analyzer.py 捕获并 diff EXPLAIN 计划。这就是驱动查询回归场景的东西——它在 schema 变化前后保存计划快照并计算差异。结果存储在 reports/plans/ 下作为时间戳 JSON 文件。
Grafana 是自动配置的。benchmark_results 表在每次运行后由 export_metrics.py 填充,grafana/dashboards/benchmark.json 中的仪表板被自动加载。不需要手动设置。
最有趣的结果来自查询回归场景。在通过迁移 002_add_indexes.sql 添加复合索引(idx_orders_user_created)后,order_history 的 EXPLAIN 计划戏剧性地改变了:
在索引之前——Sequential Scan:
Execution time: 0.532ms
规划器扫描了整个 orders 表(接触 39 个块)并过滤了 2,497 行以找到 3 条匹配的记录
Total cost estimate: 101.27
在索引之后——Bitmap Index Scan:
Execution time: 0.090ms
规划器直接使用 idx_orders_user_created,仅读取 5 个块
Total cost estimate: 10.92
这是执行时间减少了 83%,规划器成本下降了约 10 倍——从触及 2,500 行的全表扫描降到针对性的索引查找。如果没有回归跟踪,除非有人碰巧手动运行 EXPLAIN,否则这种变化是看不见的。
这正是值得在 CI 中拥有的验证类型:你添加一个索引,运行套件,获得清晰的前后 diff,确认优化确实奏效了。
这是我想花真正时间的地方,因为 AI 辅助工作流和技术输出本身一样有趣。
我实际做的是提示 AI 提出一个项目想法,精化范围,然后迭代地让它生成解决方案——先是结构,然后是单个模块,然后是 CI 管道。我没有从零开始写很多代码。我做的是花费大量时间阅读它生成的内容,质疑测试逻辑是否有意义,并验证场景是否与它们应该模拟的真实问题相匹配。
这个工作流与我自己写所有代码相比有什么不同的感觉:
我花更多时间思考测试是否正确,而不是如何实现它们。对于一个 QA 焦点的项目,这实际上是一个好转变——但感觉陌生。
AI 在样板和结构(docker-compose 设置、pytest fixtures、文件组织)上表现出色,在逻辑上还不错,但在边界情况和测试有效性上需要指导。
我对结果的"所有权"感到真正不确定。代码有效,我理解它,我在整个过程中做出了真正的决定——但没有 AI 的帮助,我也无法在两天内交付它。这是一个奇怪的感受。
它真正帮助的地方:启动 Docker + Grafana 集成是我手动花半天的事情。AI 在几分钟内拿出了一个有效的 docker-compose.yml 和自动配置的仪表板。仅这一点对于一个 POC 就值得了。
它不足的地方:AI 倾向于生成看起来很自信的代码,需要仔细审查。一些生成的 SQL 文件的列名与 schema 不匹配。N+1 检测逻辑需要额外的一遍来正确处理并发情况。这些都不是障碍,但它们强化了人类在循环中不是可选的——这是工作本身。
我会继续尝试 AI 辅助工作流,特别是对于测试工具和 POC。如果你构建过类似的东西或对这个方法有想法,我很想在评论中听到。你可以在这里检查完整的解决方案。
有些评论可能只对登录的访问者可见。登录以查看所有评论。
对于进一步的行动,你可以考虑屏蔽这个人和/或报告滥用。