关于 db-optimize
db-optimize 是面向开发者的数据库性能审计技能,可检查代码库和数据库。它分析慢查询、执行计划、N+1 模式、端点调用数及潜在连接机会,并汇总优先级。
主要功能
- 01检查慢查询日志
- 02分析 EXPLAIN 输出
- 03检测 N+1 查询模式
- 04统计各端点数据库调用
- 05发现连接查询机会
适用场景
- 01找出平均耗时较高的查询
- 02检查执行计划中的扫描与排序
- 03定位循环中重复触发的查询
- 04确定需要优化的数据库端点
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ ariadoss/ superskills --skill db-optimize安装后在 Claude Code 中输入/db-optimize确认已加载。
详细介绍
/db-optimize
全面的数据库性能审计:检测 N+1 问题、分析 EXPLAIN、审查慢查询日志、查找索引缺失、发现 JOIN 机会,并统计各端点的调用次数。
步骤 1:检查 DBMAP.md
[ -f DBMAP.md ] && echo "DBMAP_EXISTS=true" || echo "DBMAP_EXISTS=false"
如果 DBMAP_EXISTS=false,请告知用户:“未找到 DBMAP.md。请先运行 /dbmap 生成架构映射 — 此审计会用它来交叉核对索引和表结构。”
步骤 2:慢查询日志
检查是否存在或能否访问慢查询日志:
# PostgreSQL — check pg_stat_statements if available
psql "$DATABASE_URL" -c "SELECT query, calls, total_exec_time, mean_exec_time, rows FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 20;" 2>/dev/null || echo "PG_STAT_UNAVAILABLE"
# MySQL — check slow query log location
mysql -e "SHOW VARIABLES LIKE 'slow_query_log%';" 2>/dev/null || echo "MYSQL_UNAVAILABLE"
如果两者都不可用,请扫描代码库,查找查询日志输出文件:
find . -name "*.log" | xargs grep -l "slow\|duration\|query_time" 2>/dev/null | head -5
按平均执行时间排序,报告找到的 10 条最慢查询。每条查询需包含:查询文本(截断至 120 个字符)、调用次数、平均耗时(ms)、总耗时(ms)。
步骤 3:EXPLAIN 分析
对步骤 2 中识别出的每条慢查询(或用户提供的任何查询)运行 EXPLAIN ANALYZE:
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) <query>;
解读输出并标记:
- 大型表(>1000 行)上的 Seq Scan — 缺少索引
- 行数估算较高的 Nested Loop — 考虑使用 Hash Join 或索引
- 内存使用量较高的 Hash Join — 考虑调整 work_mem
- 未使用索引的 Sort — 考虑为 ORDER BY 列添加索引
- 实际行数远大于估算行数 — 统计信息过时,建议运行
ANALYZE <table>
按以下格式整理发现:
EXPLAIN: <query summary>
⚠ Seq Scan on orders (5,432 rows) — add index on orders.user_id
⚠ Sort on created_at — add index on events(created_at)
✓ Index Scan on users — OK
步骤 4:检测 N+1 问题
扫描代码库,查找 N+1 模式:
需要标记的 ORM 模式:
- 循环中包含数据库调用(
.find、.where、.query、.fetch、.get、.filter、.select) - 在循环内访问关联关系,但未进行预加载(在循环内的模型实例上调用
.user、.author、.comments、.items等) - 在循环内对数据库调用进行多次顺序 await
# Find loops with DB calls inside
grep -rn "for\|each\|map\|forEach\|loop" --include="*.rb" --include="*.py" --include="*.js" --include="*.ts" --include="*.go" --include="*.java" . | head -5
对于存在循环和查询模式的每个文件,阅读相关上下文并判断是否确实存在 N+1 问题。
按以下格式标记:
⚠ N+1 DETECTED: app/controllers/orders_controller.rb:45
Loop over orders calls order.user on each iteration
Fix: Use includes(:user) / eager_load(:user) / preload(:user)
SQL impact: 1 query → 1+N queries (N = number of orders)
步骤 5:各端点的数据库调用审计
扫描路由处理程序/控制器操作,统计查询次数:
对于找到的每个端点/操作,统计不同数据库调用的次数:
- 直接 SQL:
db.query、connection.execute、pool.query - ORM:
.find、.findAll、.where、.first、.save、.create、.update - 循环内的每次调用均计为 N 次调用
将数据库调用超过 3 次的端点标记为待优化对象:
⚠ HIGH DB CALL COUNT: GET /api/orders (OrdersController#index)
8 DB calls detected:
- Order.all (1)
- order.user (N — N+1 pattern)
- order.items (N — N+1 pattern)
Fix: Use a single query with LEFT JOINs or eager loading
步骤 6:JOIN 机会
查找多个顺序查询获取相关数据、且可合并为单个 LEFT JOIN 的位置:
模式:第二个查询使用第一个查询结果中的 ID。
💡 JOIN OPPORTUNITY: app/services/dashboard_service.rb:23-31
Query 1: SELECT * FROM orders WHERE user_id = ?
Query 2: SELECT * FROM items WHERE order_id IN (...)
Fix: SELECT o.*, i.* FROM orders o LEFT JOIN items i ON i.order_id = o.id WHERE o.user_id = ?
步骤 7:摘要报告
输出按优先级排序的问题报告:
## DB Optimization Report
### Critical (fix immediately)
- N+1 queries: X found
- Endpoints with >10 DB calls: Y found
### High Priority
- Slow queries (>100ms mean): Z found
- Missing indexes on FK columns: W found (see DBMAP.md Index Analysis)
### Optimization Opportunities
- JOIN consolidations: V found
- EXPLAIN issues: U found
### Recommended next steps
1. [highest impact fix]
2. [second fix]
3. ...
询问用户:“要我现在实施其中任何一项修复吗?我可以从影响最大的问题开始。”
评论
支持 Markdown