2024 年 7 月 23 日

性能基准:比较 TypeScript ORM 和数据库之间的查询延迟

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

目录

TLDR(太长不看)

为您的应用程序选择最佳 ORM 需要考虑多个因素,其中查询性能是重要因素之一。

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


查看基准测试结果

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

根据我们收集的数据,无法得出结论说某个 ORM 始终比另一个 ORM 表现更好。相反,这取决于各自的查询、数据集、模式以及执行查询的基础设施。

请查看下面的性能清单,以确保您的 Prisma ORM 查询获得最佳性能。

我们的基准测试方法

测量和比较查询性能可能是一项艰巨的任务,并且在创建公平的比较时需要考虑很多因素。

通过我们的基准测试,我们希望在确保基准测试公平且有意义之间取得平衡,以帮助人们就其下一个项目使用哪个 ORM 做出明智的决定,同时保持简单易懂,而没有太多间接层或数据处理。

您可以在此处找到我们用于测量查询性能的应用程序。

设置

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

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

例如,来自 Prisma ORM 的普通 findMany 查询可以按如下方式测量

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

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

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

数据准备

使用 faker.js 播种示例数据。为了以确定性的方式重新创建相同的示例数据集,向 faker 实例提供了一个 seed 值。

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

基准测试执行

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

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

为了收集我们的数据,我们在生产基础设施上执行了基准测试,以模拟真实的使用场景。这些脚本已从具有此规格的 EC2 实例执行

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

发布基准测试结果

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

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

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

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

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

注意事项

基准测试本质上是一个棘手的话题,并且很难做到正确。当公司发布性能基准测试时,这些测试通常会表明他们的产品是市场上最快的,同时让其他人难以重现结果,并且模糊了从原始数据收集到结果呈现的路径。

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

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

用户体验研究表明,低于 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 上打开一个 issue,详细说明您的查询,以便我们可以确保它尽可能快!

使用 Prisma Optimize 的见解和建议

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

Optimize 会捕获通过 Prisma ORM 发送到您数据库的所有查询,并提供详细的跟踪信息,让您深入了解它们的性能。将来,Optimize 将能够为您提供加速慢查询的建议,例如,建议何时返回过多的行或在您的模式中定义索引

查看基准测试结果

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

不要错过下一篇文章!

注册 Prisma 新闻通讯