PAYATHON 2026

Prisma findFirst() 比 findMany() 后取首项更快吗?

数据阿明

应该选哪一种?

对于题目中的两段代码,如果只需要一条记录,应优先使用 findFirst()。不带过滤条件和数量限制的 findMany() 会获取全部记录,之后再用 users[0] 取首项,这不会让数据库只返回一条。数据量增大时,多余的记录会增加传输、结果解析和应用内存开销。Prisma CRUD 文档

如果 getById 按主键或唯一字段查询,通常应选择 findUnique()。如果查询条件可能匹配多条记录,而你需要其中第一条,则选择 findFirst()。

性能差异来自哪里?

users[0] 在 await prisma.users.findMany() 完成后才执行,此时查询结果已经返回到应用。取数组首项的开销很小,主要差别在于前面的查询获取了多少数据。

findFirst() 用于获取第一条匹配记录,普通查询通常会在数据库查询中限制结果数量。不过,只返回一条记录并不意味着数据库只检查一行;过滤条件、排序和索引仍会影响执行成本。

如果 where 条件最多只能匹配一条记录,例如查询唯一 ID,那么 findMany() 也不会返回大量数据。此时两种写法的实际耗时可能接近,不能断言 findFirst() 在所有场景中都更快,也不能给出固定的提升比例。

单条资源查询怎么写?

沿用题目中的 prisma.users,下面假设 id 是数值类型的主键或唯一字段;实际项目应使用生成的模型属性和字段类型。

async function getById(id: number) {
  return prisma.users.findUnique({
    where: { id },
  });
}

如果需要按 ID 升序取第一条记录,可以这样写:

const user = await prisma.users.findFirst({
  orderBy: { id: 'asc' },
});

findUnique() 通过主键或唯一条件定位记录,findFirst() 获取符合条件的第一条记录。两者未找到记录时都返回 null。Prisma Client API 文档

findMany({ take: 1 }) 可以替代吗?

可以显式限制数量,再取首项:

const users = await prisma.users.findMany({
  take: 1,
  orderBy: { id: 'asc' },
});

const user = users[0] ?? null;

这样可以避免获取全部记录。对于条件和排序相同的普通查询,它与 findFirst() 的工作量通常接近;准确差异需要结合实际生成的查询和执行计划判断。查询单条记录时,直接使用 findFirst() 的返回值也更符合用途。

还需要注意什么?

  • 没有 orderBy 时,不应依赖数据库每次都返回同一条“第一条”记录。需要稳定结果时,应指定排序,并在必要时加入唯一字段消除排序并列。
  • 空数组的 users[0] 是 undefined,而 findFirst() 返回 null。替换写法时,要检查 API 如何处理空结果。
  • 排查性能时,先比较相同的过滤条件、排序和返回字段,再查看查询日志与数据库执行计划。单次计时容易受到连接建立、缓存和网络波动的影响。

备注:内容仅供参考。