如何让Prisma生成带GROUP BY的高效PostgreSQL查询?
解决方案:无需原生SQL实现高效Prisma查询
可以通过Prisma的NOT EXISTS结合子查询去重的方式,生成等价于添加GROUP BY的高效SQL,避免物化大量重复数据。
方式一:使用distinct去重
this.prismaService.users.findMany({ where: { NOT: { exists: this.prismaService.events.findMany({ select: { userId: true }, where: { userId: { not: null }, timestamp: { gte: timeWindowEnd }, }, distinct: ['userId'], // 对user_id去重,大幅缩小中间结果集 }), }, }, });
方式二:使用groupBy聚合
this.prismaService.users.findMany({ where: { NOT: { exists: this.prismaService.events.groupBy({ by: ['userId'], where: { userId: { not: null }, timestamp: { gte: timeWindowEnd }, }, _count: { userId: true }, // 聚合函数为必填项,此处仅用于满足语法要求 }), }, }, });
效果说明
这两种方式生成的SQL会分别包含DISTINCT user_id或GROUP BY user_id,PostgreSQL会对查询结果去重,将中间结果从十几万条压缩至几千条,执行计划会切换为HashAggregate而非物化大量重复行,性能和手动添加GROUP BY的原生SQL一致,执行时间从200秒级降至几十毫秒。
Prisma原生的none语法目前不会自动添加去重逻辑,因此需要通过上述方式手动优化查询逻辑,无需编写原生SQL。
内容的提问来源于stack exchange,提问作者Sjlver
相关产品推荐
相关产品推荐

