关于 db-query-patterns
db-query-patterns 是检查 ORM 源码和原始 SQL 查询形态的数据库审计技能,帮助开发者发现可能影响性能的访问模式;静态发现仅作方向性判断,需运行时计划确认。
主要功能
- 01检测热点路径中的 SELECT *
- 02查找结构性 N+1 查询
- 03标记深层 OFFSET 分页
- 04识别非 SARGable 谓词
- 05提供基于 EXPLAIN 的验证指引
适用场景
- 01检查 ORM 和 SQL 中低效的查询形态
- 02定位分页深度增加后变慢的模式
- 03通过执行计划验证疑似查询问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ hainrixz/ claude-db --skill db-query-patterns安装后在 Claude Code 中输入/db-query-patterns确认已加载。
详细介绍
db-query-patterns (M13)
查询的编写方式决定了是否能使用 M11 中的索引。本模块会检查 ORM 源码和原始 SQL 中的查询形态。影响 性能与扩展性评分(performance 轴、关系型 Query 权重 18,与 M3/M19 共用)。
检查内容
SELECT *— 获取所有列会使覆盖索引失效、增加网络和缓存负担,并使代码依赖列的顺序。在热点路径中标记。- 结构性 N+1 — 在循环中执行查询,或逐行延迟加载关联数据,而这些操作本应通过单次联接或批量
IN完成。静态检测仅提供方向性判断(循环的运行时基数未知)——指出代码结构,但绝不声称具体行数。 - OFFSET 分页 —
LIMIT n OFFSET m的性能会随分页深度线性下降;深分页应使用键集/游标分页(WHERE id > $last ORDER BY id LIMIT n)。 - 非 SARGable 谓词 — 对索引列使用函数包装(
WHERE lower(email)=…、WHERE date(created_at)=…、前导通配符LIKE '%x'、隐式类型转换),导致无法使用索引。建议创建表达式索引或重写谓词。对于前导通配符 /LIKE '%x%'的情况,B 树永远无法提供帮助——应明确给出解决方案:在该列上创建pg_trgmGIN/GiST 索引,或在全文搜索负载较重时使用专用搜索引擎。
评分 / 轴
仅影响 性能(关系型 Query 权重 18;文档型/时序型/图谱型配置中的 Query 类别)。
Tier-0(静态)
通过 Grep 查找 ORM 调用位置和原始 SQL 中的 SELECT *、函数包装的索引列、前导通配符 LIKE 和 OFFSET;检测循环 / .map / 逐项关联访问中的查询调用,以识别 N+1。所有查询模式发现都只能基于源码作出方向性判断——确认实际执行计划/成本需要运行时验证(needs_api / Tier-2)。
Tier-1/2(验证查询)
EXPLAIN (ANALYZE, BUFFERS) <the suspect query>;
方法 explain_plan。存在索引时出现 Seq Scan,可确认谓词非 SARGable;actual rows × loops 可确认 N+1 放大效应。Tier-2 的 pg_stat_statements(按 total_exec_time 排序)可揭示真实热点查询——没有它,热点判断只能是方向性的。
发现项
按照 schema/finding.schema.json 输出发现项。示例:
M13.orders.select_star_hot_path— 高频读取中的SELECT *(severity:2,warn,轴为performance,置信度为directional,fixable: proposed)。M13.users.n_plus_one_posts— 循环中的逐行关联加载(severity:3,warn,directional,fixable: advisory— 需要在应用端预加载 / 批处理)。M13.feed.offset_deep_pagination— 使用OFFSET进行深分页(severity:2,warn,directional,fixable: proposed— 改写为键集分页)。M13.users.non_sargable_lower_email— 函数包装的索引列(severity:3,warn,directional,fixable: proposed— 创建表达式索引或重写谓词)。
每项发现:evidence.observed 原样引用查询 / 调用位置(已对密钥脱敏);verification.reproduce 是上述引用 $DATABASE_URL 的 EXPLAIN,或针对该模式的 grep;expected_impact 使用分档数值并标注置信度(不得只给出百分比)。
诚实性
- N+1 按设计仅提供方向性判断:循环执行两次没有问题,但同一循环处理 1 万行就不一样了——静态分析无法判断具体情况,因此既不会给出上限,也不会引用倍数。
- 在小型查找或一次性管理查询中,
SELECT *无害——严重程度应仅针对热点路径。 - 会改变结果语义的重写(键集分页、谓词结构调整)应标记为
proposed/advisory,绝不可设为auto;新增表达式索引可标记为proposed。