【问题标题】:Why does deleteMany use 2 queries?为什么 deleteMany 使用 2 个查询?
【发布时间】:2021-09-20 11:33:46
【问题描述】:

我注意到deleteMany 在我指定where 时使用了两个查询。它首先选择要删除的行的主键,然后使用DELETE FROM WHERE id IN (...) 查询将它们删除。

这个有什么用?而不是WHERE id IN (...) 查询,对我来说,只选择DELETE 查询本身中要删除的行会更有意义。

举个例子:

await this.prismaService.cardSet.deleteMany({ where: { steamAccountId: steamAccount.id } });

运行:

SELECT "public"."CardSet"."id" FROM "public"."CardSet" WHERE "public"."CardSet"."steamAccountId" = $1;
DELETE FROM "public"."CardSet" WHERE "public"."CardSet"."id" IN ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,...);

以下对我来说似乎更有效:

DELETE FROM "public"."CardSet" WHERE "public"."CardSet"."steamAccountId" = $1;

【问题讨论】:

    标签: prisma prisma2


    【解决方案1】:

    我无法评论导致 Prisma 库作者将deleteMany 操作转换为两个单独的 SQL 语句的技术决策。

    但是,ORM(Prisma 和其他)通常并不总能生成完美高效的 SQL 查询。在许多情况下,绝对可以直接在 SQL 中编写更优化的查询。这是使用 ORM 时必须注意的权衡。

    如果您的用例真的需要这个 deleteMany 操作尽可能高效,您可以考虑使用 Prisma 的 $queryRaw 功能直接编写更高效的 SQL 查询。您可以在 Prisma 文档的Raw database access article 中找到更多信息。

    在我看来,除非您确定手动 SQL 查询确实会以某种有意义的方式提高您的性能,否则我不会为这种特殊情况而烦恼。

    【讨论】:

    • 我很清楚 ORM 并不总是理想的,但是这个案例让我印象深刻,因为它看起来很容易优化。我确实最终使用了$queryRaw。我使用deleteMany 截断表,因此手动TRUNCATE 查询要快得多。我最后也在 Prisma 的 GitHub 讨论中问了这个问题,并收到了以下关于为什么 deleteMany 使用两个查询的答案:github.com/prisma/prisma/discussions/…
    • 回想起来,我的回答可能过于简单化了。对此深表歉意,并感谢您提供描述问题背后非常具体原因的链接!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多