第11章 Prisma Postgres 查询洞察:监控慢查询与 Prisma 调用映射
第11章 查询洞察
查询洞察:监控慢查询,将 Prisma 调用映射到 SQL,并使用 Prisma Postgres 应用针对性优化。查询洞察内置于 Prisma Postgres,帮助你理解哪些查询速度慢、为何资源消耗高以及下一步该如何调整。它不会自动重写你的查询或 schema。
查询洞察取代了 Prisma Optimize,现在随 Prisma Postgres 免费提供。你可以立即在 Prisma Console 中试用。
仪表盘
主查询洞察视图为你提供数据库查询活动的实时概览。
在页面顶部,你可以查看:
- 选定时间段内的平均延迟
- 每秒查询数
- 每个指标的时间序列图表
- 悬停显示精确时间戳和数值
- 回放控制,用于逐步浏览已捕获的活动
这有助于判断问题是持续性的、突发性的,还是与某个短时间窗口相关。
查询列表
在图表下方,查询洞察显示一组聚合查询列表。
每行包含:
- 延迟
- 执行次数
- 读取量
- 最后出现时间
- SQL 语句结构
你可以使用表格上方的控件来:
- 按表筛选结果
- 排序列表,优先显示最重要的查询
- 聚焦于重复执行、高读取量或最近执行的语句
利用此视图决定优先调查哪些查询模式。
查询详情
选中某个查询后,会打开该语句的详细视图。
详细视图显示:
- 统计摘要,描述查询涉及的表、执行次数、平均延迟及每次调用的读取量
- 完整的 SQL 语句
- AI 生成的分析,解释该查询是否需要优化及原因
- 可复制的提示词,你可以直接粘贴到编辑器或 AI 编程助手中,以应用建议的修复方案
AI 分析会描述性能问题的可能原因、推荐的具体更改以及预期影响。可复制的提示词包含你的实际查询及上下文信息,因此你可以将其粘贴到编辑器或 Cursor、Copilot、Claude 等工具中,无需切换上下文即可获得具体的代码更改。
将 AI 分析视为起点而非最终答案。在发布任何建议的更改前,请务必进行审核。
Prisma ORM 归因
使用 Prisma ORM 时,查询洞察可以追踪从应用程序代码到所生成 SQL 的完整链路。这意味着即使单个 Prisma 调用扩展为多条 SQL 语句,你也能看到是哪个 prisma.* 调用产生了慢查询。
对于原始 SQL 或在 Prisma ORM 之外发出的查询,查询洞察仍会显示完整的 SQL 行为,但 ORM 级别的归因需要以下步骤。
设置
要启用 ORM 归因,请安装 @prisma/sqlcommenter-query-insights 包:
npm install @prisma/sqlcommenter-query-insights
然后在 PrismaClient 构造器中将其传递给 comments 选项:
import "dotenv/config";
import { PrismaClient } from "../generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
import { prismaQueryInsights } from "@prisma/sqlcommenter-query-insights";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
export const prisma = new PrismaClient({
adapter: adapter,
comments: [prismaQueryInsights()],
})
这会给查询添加 SQL 注释标记,以便查询洞察将 SQL 语句映射回生成它们的 Prisma 调用。它基于 Prisma Client 的 SQL 注释功能构建。
可用性
查询洞察随 Prisma Postgres 免费提供。你可以立即在 Prisma Console 中试用。
典型问题
当查询洞察将数据库症状与具体的代码更改联系起来时,它最为有用。
| 问题 | 可能看到的现象 | 典型修复方法 |
|---|---|---|
| N+1 查询 | 单次请求产生高查询数 | 使用嵌套读取、批处理或连接(Joins) |
| 缺少索引 | 相对于返回行数,读取量过高 | 为过滤模式添加正确的索引 |
| 过度获取 | 宽行或大型负载 | 使用 select 获取更少的字段 |
| 基于偏移的分页 | 越深入的分页读取量越大 | 切换到游标分页 |
| 大型嵌套读取 | 高读取量和大型负载 | 限制字段、限制深度或拆分查询 |
| 重复查询 | 相同的语句结构频繁执行 | 在适当时缓存或重用结果 |
如何使用
当某个端点变慢时,查询洞察提供一个实用的工作流:
- 打开查询洞察,浏览延迟和每秒查询数图表。
- 排序或筛选查询列表,以隔离昂贵的语句。
- 打开查询详细视图。
- 阅读 AI 分析并检查 SQL。
- 复制建议的提示词并粘贴到编辑器中。
- 审核建议的更改,然后在代码或 schema 中应用它。
- 重新运行工作负载,并再次比较相同的信号。
在大多数情况下,下一步更改属于以下类别之一:
- 更改 Prisma 查询结构
- 添加或调整索引
- 返回更少的字段或行
- 缓存重复工作
示例
一个常见的例子是 N+1 模式:
const users = await prisma.user.findMany({
select: { id: true, name: true, email: true },
});
for (const user of users) {
await prisma.post.findMany({
where: { authorId: user.id },
select: { id: true, title: true },
});
}
查询洞察通常会显示:
- 一个用于加载用户的查询
- 许多用于加载文章的重复查询
- 相同语句结构的高执行次数
- 超出该路由所需的高读取量和延迟
在这种情况下,可能的修复方法是使用一次嵌套读取来加载相关文章:
const usersWithPosts = await prisma.user.findMany({
select: {
id: true,
name: true,
email: true,
posts: {
select: {
id: true,
title: true,
},
},
},
});
同样的模式适用于其他问题。查询洞察帮助你识别昂贵的查询结构,理解其昂贵原因,并选择下一步验证的更改。
下一步
- 对于高并发工作负载,查看 连接池
- 在为其他工具选择连接字符串时,使用 连接数据库
- 参阅 Prisma Client 查询优化 了解相关的 Prisma ORM 模式
在 GitHub 上编辑