July 23, 2024

性能基准测试:比较不同 TypeScript ORM & 数据库的查询延迟

我们创建了开源的性能基准测试,以比较 Prisma ORM、TypeORM 和 Drizzle ORM 在不同数据库提供商(如 AWS RDS 上的 PostgreSQL、Supabase 和 Neon)之间的查询延迟。继续阅读,了解我们的方法论以及哪种 TypeScript ORM 最快。

目录

内容摘要

选择最适合您应用的 ORM 需要考虑多个因素,其中查询性能是一个重要因素。

为了帮助您决定为 TypeScript 应用选择哪个 ORM,我们创建了开源的性能基准测试,比较了三个 ORM 库的查询性能:Prisma ORM、TypeORM 和 Drizzle ORM(使用它们的 Query API)。


查看基准测试结果

那么,哪个 ORM 最快?这个(也许令人不满意的)答案是:视情况而定!

根据我们收集的数据,无法断定某个 ORM 总是比其他 ORM 表现更好。相反,它取决于具体的查询、数据集、schema 以及执行查询的基础设施。

请查看下方的性能清单,确保您的 Prisma ORM 查询性能最优。

我们的基准测试方法

衡量和比较查询性能可能是一项艰巨的任务,要进行公平的比较需要考虑很多因素。

通过我们的基准测试,我们希望在确保基准测试公平且有意义(以便人们就下一个项目使用哪个 ORM 做出明智决策)与保持简单易懂、避免过多间接层或数据处理之间取得平衡。

您可以在这里找到我们用于衡量查询性能的应用。

设置

我们为 Prisma ORM、TypeORM 和 Drizzle ORM 创建了 14 个等效查询。这些查询针对一个包含 4 个 Prisma 模型(由于一个隐式 m-n 关系在底层使用了一个额外的关联表,实际有 5 个表)的schema发送。

每个查询的延迟通过performance.now() 使用此函数进行测量

例如,Prisma ORM 的普通findMany查询可以如下测量

每个 ORM 和每个数据库对应一个脚本(例如 prisma-postgres.ts),该脚本单独测量所有 14 个查询的延迟,并将结果存储在 .csv 文件中。

脚本已在 EC2 实例上执行,针对托管在各种提供商上的 PostgreSQL 数据库

在每个脚本的开始建立数据库连接,并在结束时关闭。

数据准备

样本数据使用faker.js进行填充。为了以确定性方式重新创建相同的样本数据集,需要向 faker 实例提供一个seed值。

运行基准测试时,数据集的大小是可配置的。它决定了每张表创建多少条记录。例如,如果创建了大小为1000的数据集,则 CustomerProductAddress 表中将各有 1k 条记录,而 Order 表中将有 10k 条记录(Order 表与其 Product 表具有多对多关系,因此乘以 10 的因子,使数据集更真实)。

基准测试执行

要执行基准测试,可以按如下方式调用脚本

这将对每张表包含 1000 条记录的数据集执行预定义的查询 500 次。数据库 URL 也可以作为环境变量提供。

为了收集数据,我们在生产环境中执行了基准测试,以模拟真实世界的使用场景。脚本是在具有此规格的 EC2 实例上执行的

我们使用的数据库具有以下规格

发布基准测试结果

我们已将执行的基准测试结果发布到:https://benchmarks.prisma.io

该表格显示了我们为衡量查询延迟执行的 500 次迭代的中位数。请注意,我们通过移除高于第 99 个百分位数 (p99) 的值,去除了 500 次迭代中的异常值。

表格的列代表三个 ORM 库,行显示已进行基准测试的查询。

展开单元格时,您可以查看有关查询的一些详细信息,例如

  • 产生结果的查询实际代码片段。
  • 显示收集数据的分布的直方图。在这些图表中,左侧更高的条形更好,因为它们表明更多迭代具有较低的延迟。

注意事项

基准测试本身是一个复杂且难以正确处理的话题。当公司发布性能基准测试时,通常会显示他们的产品是市场上最快的,同时使其他人难以重现结果,并模糊了从原始数据收集到结果呈现的过程。

我们尽力创建了一个公平、中立且易于理解并能产生有意义结果的设置。尽管如此,在查看基准测试结果时,以下是一些需要注意的事项

  • TypeORM 和 Drizzle ORM 在其 API 方面更有限制,一些 Prisma ORM 查询(例如嵌套创建)无法通过其更高级的抽象来表达。在这种情况下,我们不得不使用它们的 SQL 查询构建器。
  • 由于网络延迟,迭代结果存在预期的差异。为了减少其影响,我们执行了 500 次基准测试,并在发布的基准测试结果中使用了中位数和直方图来展示结果。
  • 我们还确保执行查询的机器与访问的数据库位于同一区域,以保持网络延迟最低。
  • 在我们的基准测试中,我们没有采取任何措施来减少数据库级别或操作系统级别缓存的影响。
  • 所有基准测试迭代都使用了相应 ORM / 驱动库的默认连接池大小。
  • 虽然我们努力使基准测试设置尽可能真实,但在 schema 和查询方面不得不做出一些权衡。例如,我们没有向 schema 添加特殊索引,有时故意使用非常简单的查询,以便能够正确比较每个 ORM 的更高级 API。

我们付出了很多努力,让您可以轻松地自己运行基准测试,所以请尝试一下,如果您想贡献改进,请随时联系我们

哪个 ORM 最快?

虽然可能令人不满意,但答案往往是:视情况而定。性能是一个复杂且微妙的话题,取决于多种因素,并且众所周知难以预测。

请参阅下方的性能清单,确保您的查询速度达到最佳。

虽然无法对该问题提供一个确切的答案,但我们可以尝试分析一些模式。

不同数据库提供商之间的差异较小

首先,我们发现不同数据库提供商之间的差异通常可以忽略不计。例如,仅看普通的findMany查询,我们可以从中位数和直方图分布中看到,性能差异很小

Prisma ORMDrizzle ORMTypeORM
Supabase8.00ms23.09ms5.24ms
AWS RDS6.59ms19.19ms4.20ms
Neon11.43ms29.35ms7.25ms

大概 RDS 有优势,因为基准测试脚本是从同一安全组内的 EC2 实例执行的,而 Supabase 和 Neon 数据库通过公共互联网访问。

欲了解更多信息,请务必访问基准测试网站,查看我们的结果,或使用您选择的数据库提供商自行运行基准测试。

大多数查询的性能处于相似水平

如果您放大并从远处查看结果,您会注意到大多数查询的实际性能处于相似水平,仅有几毫秒的差异。例如,以下是我们收集的 AWS RDS 上的结果

UX 研究表明,低于 100 毫秒的延迟用户无法察觉,并且仍然会让系统感觉即时响应,因此在大多数情况下,这些微小的差异可能不应该成为您为下一个项目选择使用哪个 ORM 的决定因素。

当然,数据库查询延迟只是您正在构建的应用整体性能中的一个因素,因此务必衡量和优化其他方面,特别是系统拥有的所有网络边界(例如 HTTP 层)。

主要异常值:嵌套查找所有

嵌套查找所有查询在所有 ORM 和所有数据库提供商中都特别慢。这是一个简单的查询,看起来像这样

Prisma ORM

Drizzle ORM

TypeORM

以 RDS 为例,以下是我们收集的结果中的中位数

Prisma ORMDrizzle ORMTypeORM
嵌套查找所有62.4ms948.29ms56.34ms

事实证明,对于所有 ORM 而言,此查询比其他查询慢得多,因为它从两个不同的表中获取数据,并且返回的数据量很大。

结论

我们收集的数据无法对每个 ORM 的单独性能做出确切结论。关于查询性能的残酷事实是,使用每个 ORM 库都可以编写快速或慢速的查询。

归根结底,应用的大部分性能取决于开发者遵循最佳实践(参见下方的性能清单)、识别慢速查询并随时间优化它们的能力。

提升您的 Prisma ORM 查询性能

性能在 Prisma 对我们至关重要,近期我们在这方面投入了大量精力来改进 Prisma ORM 的各个方面,例如引入使用数据库级别 JOIN 的选项,在v5中实现许多性能改进,将无服务器冷启动速度提升 9 倍,或在最新的5.17.0版本中将$queryRaw的速度提高 2 倍。

Prisma ORM 性能清单

这是一份基本清单,可帮助您确保您的 Prisma ORM 查询性能达到最佳

  • 将服务器和数据库托管在同一区域。
  • 为您查询中频繁使用的列添加索引。
  • 确保生产环境中至少有 3 个 CPU 内核可用。
  • 衡量性能,并在需要时使用原始 SQL 优化查询。
  • 使用 Prisma ORM 的OpenTelemetry 跟踪指标功能监控您的查询。
  • 为您的数据库添加缓存层(例如Prisma Accelerate)。
  • 如果您的应用是无服务器的,请遵循无服务器性能的最佳实践

如果您遵循这些建议后仍然发现查询缓慢,请在 GitHub 上提交议题,详细说明您的查询,以便我们确保其速度应有的快!

使用 Prisma Optimize 获取洞察和建议

为了支持您衡量性能并加快 Prisma ORM 查询速度,我们最近推出了Prisma Optimize

Optimize 捕获通过 Prisma ORM 发送到您数据库的所有查询,并通过详细的跟踪信息提供其性能洞察。未来,Optimize 将能够为加快慢速查询提供建议,例如推荐何时返回过多行或在 schema 中何处定义索引。

查看基准测试结果

您可以在https://benchmarks.prisma.io找到我们基准测试运行的结果。查看一下,并在XDiscord上告诉我们您的想法。我们特别渴望听到如何使此基准测试对您更有帮助,并欢迎改进建议!

不要错过下一篇文章!

订阅 Prisma 新闻通讯