您的 ORM 正在隐藏导致缓慢查询的行

2026年8月10日1 次浏览来源:Dev.to阅读原文

我在为节点建造一个运行时间N+1查询探测器。

侦测部分在第一个下午起作用.

告诉你代码的哪一行引起问题 花了相当长的时间 并教会了我一些关于 ORMs 如何执行我以前没想过的询问 这就是那个故事,还有修补。

症状 探测器是您数据库驱动程序的工具 。

当同一个查询形状在一次请求内多次运行时,它会报告它——连同发布它的文件和行,这是实际节省你时间的部分: 不错 然后,我用Drizzle指着一个应用软件, 取而代之的是: 被检测,被统计, 并归结为一无所有。

不要理论。

我的第一个直觉是 我的框架过滤器太冲动了, 它跳过,和图书馆自己的框架, 所以也许它正在吃一些它不该吃的东西。

而不是猜测,我打印了整个堆 在确切的时刻 司机被叫: 下面是回来的单曲: 12帧.

没有一个属于申请。

我的过滤器是清白的,没有东西可找。

框为什么不见了 看框11: 滴滴的查询是懒惰的 它不会运行任何东西——它会构建一个对象。

当某事调用它时,查询执行,当你写的时候,调用的东西是JavaScript运行时间,而不是你的代码.

到此为止, 您的功能已经返回 。

它的相框从堆起就消失了.

运行时间从微任务队列中取出可当量,并调用到"Drizzle",从那里起的整个呼叫链属于ORM.

因此这些信息没有被过滤出.

它不复存在。

TypeORM 没有这个问题 我估计每个手术室都一样 我测量的不是假设,而是TypeORM的精细:行号,函数名,一切。

区别在于谁触发了处决.

是您调用的函数 。

节点使链条内部的Aync堆积线跨越边界,所以你的帧一直活到驱动器.

Drizzle的在一件你造的但没打电话的货上 这就是区别——不是"Drizzle更糟糕",而是"懒惰的处决把呼叫从你的堆里移出".

值得记住下次你看着堆积的痕迹 看起来太短了 把线找回来 堆栈在行刑时无用.

但有一个时刻,呼叫者在堆放上:同时正在构建查询.

是一个简单同步的方法调用链。

因此:在施工期间抓取呼叫站点,将呼叫站去执行,让司机级的仪表使用而不用走上堆.

因为建筑和行刑是由一个...

这正是为了: 驱动程序适配器更喜欢环境值而不是自己的堆栈行走: 而ORM一方将构建者包裹起来,让链条保存呼叫站点,并执行发布: 呼叫站点被捕获一次,当你呼叫时, 与建设者旅行 通过每一个链式方法,直到某事执行它。

净结果:SQL出自驱动程序,行号出自ORM.

结果 : 这是同一文稿中的实际前后,反对PostgreSQL 16、Drizzle 04.5.2和3.4.9——真正的数据库,而不是固定装置。 35号线站点位于环线内部的呼声.

一个值得知道的陷阱 第一个版本有一个错误,花了一段时间才看到:我把它当作一种处决方法.

在 中,执行查询。

在 Drizzle 中,构建一个插入.

把它当作执行断了链条,所以每个插入都默默地失去了它的归属——同时选择保持完美的工作.

如果您写了类似的东西, 请精确地说明您目标库中哪些方法实际执行, 测试插入和选择分开 。

一个只影响你一半案子的虫子 比一个打破一切的虫子还要糟糕 因为你不会注意到的 有两件事我会说过去 美秀

分享