我们创建了开源的性能基准测试,用于比较 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
的数据集,则在 Customer
、Product
和 Address
表中将有 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 ORM | Drizzle ORM | TypeORM | |
---|---|---|---|
Supabase | 8.00ms | 23.09ms | 5.24ms |
AWS RDS | 6.59ms | 19.19ms | 4.20ms |
Neon | 11.43ms | 29.35ms | 7.25ms |
据推测,RDS 具有优势,因为基准测试脚本是从同一安全组内的 EC2 实例执行的,而 Supabase 和 Neon 数据库则通过公共互联网访问。
有关更多信息,请务必访问基准测试站点以查看我们的结果,或者使用您选择的数据库提供商自己运行基准测试结果。
大多数查询的性能处于相似的范围
如果您放大并从远处查看结果,您会注意到大多数查询实际上在相似的范围内执行,只有几毫秒的差异。例如,这是我们在 AWS RDS 上收集的结果
用户体验研究表明,低于 100 毫秒的延迟是用户无法察觉的,并且仍然使系统感觉是即时的,因此在大多数情况下,这些小的差异可能不应该成为您选择在下一个项目中使用哪个 ORM 的决定性因素。
当然,数据库查询延迟只是您正在构建的应用程序的整体性能的一个因素,因此请务必测量和优化其他方面,特别是您的系统拥有的所有网络边界(例如 HTTP 层)。
主要异常值:嵌套查找所有
嵌套查找所有查询在所有 ORM 和所有数据库提供商中都特别慢。这是一个简单的查询,如下所示
Prisma ORM
Drizzle ORM
TypeORM
以 RDS 为例,这些是我们收集的结果中的中位数
Prisma ORM | Drizzle ORM | TypeORM | |
---|---|---|---|
嵌套查找所有 | 62.4ms | 948.29ms | 56.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 上找到我们的基准测试运行结果。请查看它们,并在 X 和 Discord 上告诉我们您的想法。我们特别希望听到您关于如何使此基准测试对您更有帮助的意见,并欢迎改进建议!
不要错过下一篇文章!
注册 Prisma 新闻通讯