mcpField
D
db-optimize

db-optimize

github.com/ariadoss数据与数据库1258 次安装今天更新
代码仓库

关于 db-optimize

db-optimize 是面向开发者的数据库性能审计技能,可检查代码库和数据库。它分析慢查询、执行计划、N+1 模式、端点调用数及潜在连接机会,并汇总优先级。

主要功能

  1. 01检查慢查询日志
  2. 02分析 EXPLAIN 输出
  3. 03检测 N+1 查询模式
  4. 04统计各端点数据库调用
  5. 05发现连接查询机会

适用场景

  1. 01找出平均耗时较高的查询
  2. 02检查执行计划中的扫描与排序
  3. 03定位循环中重复触发的查询
  4. 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