首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Objection.js在哪里的查询减慢了我的Node.js应用程序?

Objection.js在哪里的查询减慢了我的Node.js应用程序?
EN

Stack Overflow用户
提问于 2018-08-10 08:40:54
回答 3查看 2.2K关注 0票数 2

好的,这基本上是一个是/不是的答案。我有一个带有postgres计划的节点应用程序运行在Heroku上。我使用Objection.js作为ORM。我在大多数端点上都要面对300+ms响应时间,并且我对此有一个理论。我想确认一下。

我的大多数api端点都会执行5-10个急切的加载。Objection.js通过执行附加WHERE查询来处理急切的加载,而不是通过使用大量联接执行一个大型查询来处理。这样做的原因是,这样的构建更容易,而且不应该对性能造成太大的损害。

但这让我想到: Heroku不像我假设的节点应用程序那样运行在相同的heroku上,所以这意味着每个查询都有延迟。难道所有这些延迟加在一起,造成总共300 of的延迟吗?

概述:如果您有单独托管的数据库,用Knex构建自己的查询比通过Objection.js生成查询要快吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-08-10 12:17:18

在此,我可以确认每一个查询都需要大约。30 of,而不考虑查询的复杂性。Objection.js确实会执行大约10个不同的查询,因为加载非常迫切,从而解释了累计的300 10。

我要走这条路,⬇

我已经开始深入编写我自己的更高级的SQL查询。看起来,您可以完成相当高级的工作,获得与急切地加载Objection.js相似的结果。

代码语言:javascript
复制
select 
  "product".*,
  json_agg(distinct brand) as brand,
  case when count(shop) = 0 then '[]' else json_agg(distinct shop) end as shops,
  case when count(category) = 0 then '[]' else json_agg(distinct category) end as categories,
  case when count(barcode) = 0 then '[]' else json_agg(distinct barcode.code) end as barcodes
from "product"
inner join "brand" on "product"."brand_id" = "brand"."id"
left join "product_shop" on "product"."id" = "product_shop"."product_id"
left join "shop" on "product_shop"."shop_code" = "shop"."code"
left join "product_category" on "product"."id" = "product_category"."product_id"
left join "category" on "product_category"."category_id" = "category"."id"
left join "barcode" on "product"."id" = "barcode"."product_id"
group by "product"."id"

这需要花费19毫秒的1000种产品,但通常的限制是25种产品,所以性能非常好。

票数 2
EN

Stack Overflow用户

发布于 2018-08-10 10:37:38

猜测这种减速发生的原因基本上是毫无用处的(无论如何,我还是要推测一下)。在这种情况下,首先要做的是测量使用300毫秒的地方。

从数据库中,您应该能够看到查询时间是否存在导致问题的慢速查询。

而且,当您使用DEBUG=knex:*环境变量集运行knex时,它会向控制台输出一些有关性能的信息。

现在,节点也有内置的特征分析支持,您可以通过在启动节点时设置--检查标志来启用该功能。然后,您将能够将节点进程与chrome工具连接起来,并查看节点使用时间的位置。例如,通过该概要文件,您将能够看到数据库查询结果解析是否主导了执行时间。

找出慢点的最好方法是隔离应用程序的慢部分,仔细检查这个部分,甚至把这个例子发布到堆栈溢出中,其他人可以告诉你为什么慢。像这样的一般解释不能为其他人提供太多的工具来帮助解决真正的问题。

Objection.js通过执行附加WHERE查询来处理急切的加载,而不是通过使用大量联接执行一个大型查询来处理。这样做的原因是,这样的构建更容易,而且不应该对性能造成太大的损害。

在反对的情况下,您可以选择您喜欢使用的急切算法。在大多数情况下(当存在一对多或多对多的关系时),与使用join相比,进行多个查询实际上具有更高的性能,因为随着连接数据量的增加和传输时间的增加,节点端的结果解析将花费太多的时间。

如果您有一个单独托管的数据库,那么用Knex构建自己的查询比通过Objection.js生成查询要快吗?

通常不会。

投机部分:

  1. 你提到了Most of my api endpoints do around 5-10 eager loads.。大多数情况下,当我在查询中遇到这种缓慢的情况时,原因是应用程序正在查询数据库中的大量数据。当查询返回数万行时,它将是一些兆字节的JSON数据。只有从数据库解析到JavaScript对象的数据量才需要几百毫秒。如果您的查询在300 be期间也导致了较高的CPU负载,那么这可能是您的问题。
  2. 缓慢的查询。有时数据库没有正确设置索引,所以查询只需线性地扫描所有表才能得到结果。从DB日志中检查缓慢的查询将有助于找到这些查询。另外,如果获得响应需要很长时间,但节点进程的CPU负载较低,则可能是这种情况。
票数 2
EN

Stack Overflow用户

发布于 2018-11-18 19:20:19

正如其他人所提到的,异议默认使用多个查询而不是联接来执行急切的加载。它比完全基于连接的加载更安全,在某些情况下会变得非常慢。您可以阅读更多关于默认急切算法这里的信息。

只需调用joinEager而不是eager方法,就可以选择使用基于连接的algoritm。joinEager执行一个查询。

反对也有一个(相当愚蠢的)默认的每个操作一个并行查询,这意味着eager调用中的所有查询都是按顺序执行的。现在,默认情况已经被删除,即使在像您这样的情况下,也应该获得更好的性能。

使用json_agg的技巧非常聪明,实际上避免了我提到的在某些情况下使用joinEager时可能出现的慢问题。但是,这不容易用于嵌套加载或其他数据库引擎。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51782415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档