mcpField
B
backend-perf

backend-perf

github.com/bhagyamudgal开发2102 次安装5 天前更新
代码仓库

关于 backend-perf

用于审查后端代码性能模式的技能,会逐项说明检查结果及适用性。面向开发者,区分通用检查与 PostgreSQL 专项检查。

主要功能

  1. 01并行执行独立异步调用
  2. 02检测顺序式 N+1 查询
  3. 03检查分页计数查询
  4. 04审查 PostgreSQL 索引覆盖
  5. 05检查稳定函数的复用
  6. 06检查竞态处理

适用场景

  1. 01合并前审查后端改动
  2. 02审计 PostgreSQL 查询计划和索引
  3. 03查找重复读取和过量字段查询

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bhagyamudgal/skills --skill backend-perf

安装后在 Claude Code 中输入/backend-perf确认已加载。

详细介绍

后端性能检查清单

我会根据手头的代码逐项检查以下内容,并逐项给出结论:已落实、无问题或不适用,并说明原因。未提及的检查,即表示我没有执行。

标记为 [pg] 的检查仅适用于 PostgreSQL。在其他存储上,我会跳过这些检查,而不是将其转换为其他存储的检查。

  • 并行异步调用。相互独立的异步调用应通过 Promise.all 并行执行,绝不能逐个等待。
  • N+1 查询。不得在顺序执行的 for 或 for await 循环中查询。应改用 IN 子句批量查询或使用联接。对少量有利于索引的查询,使用 Promise.all(items.map(q => oneQuery(q))) 并行执行,不属于顺序 N+1。限制扇出量:对于无上限的 items 列表,应明确设置上限或并发限制,因为 N 个并行查询仍会打开 N 个连接。除非 EXPLAIN 显示批量联接速度更快,否则应保留并行执行的结构,因为批量查询往往会失去逐行使用索引的优势。
  • 分页计数。计数和数据行应来自同一个查询:使用 count(*) OVER () 窗口函数或单个 CTE,而不是在数据查询旁单独执行 COUNT(*)。
  • 索引覆盖 [pg]。每个生产环境中的 WHERE 子句都需要匹配的索引。similarity(col, ...)、@@ to_tsvector(...) 或 LIKE '%pattern%' 需要在同一个 PR 中添加对应的 gin (col gin_trgm_ops) 或 gin (to_tsvector('lang', col)) 索引,或者添加一行注释引用接受顺序扫描的 ADR 或 issue。优先使用可利用索引的 % 运算符,而不是直接比较 similarity() > threshold,但必须使用匹配的阈值:% 会根据会话的 pg_trgm.similarity_threshold(默认值为 0.3)进行判断,因此应将其设为查询使用的阈值,并确认结果集等价,同时通过 EXPLAIN 确认规划器选择了该索引。
  • STABLE 函数复用 [pg]。pg_trgm.similarity 和 ts_rank 是 STABLE 而非 IMMUTABLE,因此 PostgreSQL 不会可靠地记忆同一条 SELECT 中重复的函数调用。需要使用两次的值,例如既用于投影又用于 GREATEST(...) 的值,应在 WITH ... AS MATERIALIZED CTE 中计算一次。普通子查询别名无法保证这一点。规划器可能会将其展开,并针对每一行分别计算。
  • 只选择所需列。列表接口应明确列出需要的列,而不是选择整行。
  • 复用已获取的行。用于所有权检查而获取的行,应由处理程序直接返回。不要再按 id 获取一次。
  • 重写前先执行 EXPLAIN [pg]。任何查询结构调整、批处理、联接、索引操作,或将 N 个并行查询替换为 1 个批量查询,都应提供代表性数据上当前结构与拟议结构的 EXPLAIN (ANALYZE, BUFFERS) 数值。保留速度更快的结构。在差异对比中看似更快的重写,在真实数据上可能慢 10 到 100 倍。
  • 竞态条件。当 2 个或更多写入方可能操作同一行时,应使用事务。异步操作的完成顺序并不等于代码中的顺序。应通过 await 或 Promise.all 明确指定顺序,而不是依赖偶然的串行执行。必须保持原子性的检查与写入,应在 [pg] 上使用 SELECT ... FOR UPDATE,或使用唯一约束,而不是应用层锁定。

评论

支持 Markdown