EctoN+1查询检测Skill ecto:n1-check

这个技能用于检测和修复Ecto框架中的N+1查询反模式,优化数据库访问性能。关键词包括Ecto、N+1查询、数据库优化、性能检测、Phoenix应用程序、Elixir编程。

后端开发 0 次安装 0 次浏览 更新于 3/11/2026

name: ecto:n1-check description: 检测Ecto代码中的N+1查询模式。用于审查数据库访问模式或优化性能。

N+1查询检测

识别和修复Ecto/Phoenix应用程序中的N+1查询反模式。

铁律 - 切勿违反这些

  1. 永远不要在没有预加载的情况下访问关联 - 在Enum.map之前始终预加载
  2. 循环内部不要调用Repo - 重构以批量查询
  3. 在上下文边界预加载 - 在上下文而非控制器/视图中加载关联
  4. 使用连接进行过滤 - 当通过关联过滤时,使用join + preload

检测模式

模式1:Enum.map与Repo

# 错误:N+1查询
users
|> Enum.map(fn user -> Repo.get(Order, user.order_id) end)

# 正确:使用预加载的单次查询
users
|> Repo.preload(:orders)

模式2:无预加载的关联访问

# 错误:懒加载触发N次查询
for user <- users do
  user.posts  # 为每个用户触发查询!
end

# 正确:先急加载
users = Repo.all(User) |> Repo.preload(:posts)
for user <- users do
  user.posts  # 已加载
end

模式3:嵌套关联访问

# 错误:嵌套关联的N+1查询
user.posts |> Enum.map(fn post -> post.comments end)

# 正确:嵌套预加载
Repo.preload(user, posts: :comments)

快速检测命令

# 查找附近有Repo调用的Enum.map
grep -B5 -A5 "Enum.map" lib/ -r --include="*.ex" | grep -A5 -B5 "Repo\."

# 查找关联访问模式
grep -r "\.posts\|\.comments\|\.orders" lib/ --include="*.ex"

# 查找循环中的Repo调用
grep -B3 "Repo.get\|Repo.one" lib/ -r --include="*.ex" | grep -B3 "for\|Enum"

分析命令

对于上下文模块,运行:

grep -n "Repo\." lib/my_app/[context].ex

然后验证每个查询是否有适当的预加载。

参考资料

有关详细模式,请参见:

  • references/preload-patterns.md - 高效预加载策略
  • references/query-optimization.md - 查询批处理技术