【问题标题】:typeorm create() method is extremely slowtypeorm create() 方法非常慢
【发布时间】:2021-05-23 12:55:31
【问题描述】:

我正在使用

queryRunner.manager.create(…) 

在调用 save 方法之前创建实体。

我注意到,对于拥有大量数据的特定客户,创建步骤耗时 > 2 秒。 当我用自己创建新实体替换创建时

const myEntity = new MyEntity();

它使储蓄变得更快。

创建需要这么多时间的任何原因?会不会和这个实体的关系有关?

【问题讨论】:

    标签: typeorm node.js-typeorm


    【解决方案1】:

    问题是由于 TypeOrm 在 create() 方法中转换关系实例的方式, 似乎 typeOrm 正在对 create 中的每个给定实体和每个相关实体运行转换(如果您在 create() 方法中发送完整的关系实例及其关系)。

    在进行任何修复之前,我对 create() 的调用如下所示:

    const transaction = queryRunner.manager.create(Transaction, {
          seller: sellerInstance,
          buyer: buyerInstance
        });
    

    解决方案 1:仅发送 id — 如果您仍想使用 create(),请确保不要在创建字段中发送完整的关系实例,仅发送 id。 (此字段是您真正需要的唯一内容,因为这是表中的真正参考)。

    const transaction = queryRunner.manager.create(Transaction, {
      seller: { id: sellerInstance.id },
      buyer: { id: buyerInstance.id },
    });
    

    解决方案 2:您始终可以使用 new()

    const transaction = new Transaction();
    transaction.seller = sellerInstance;
    transaction.buyer = buyerInstance;
    

    查看我的博客文章以了解有关此问题的更多详细信息:

    https://tamar-duchovny.medium.com/two-lines-change-turned-a-6-sec-request-to-300ms-cf0f13c00a75

    【讨论】:

      【解决方案2】:

      在使用对其他实体的引用时,repository.create() 也有问题。我有一个复杂的操作,在事务中它会创建几个新实体并在其他新创建的实体中引用它们。问题变得如此严重,以至于整个应用程序都出现了响应问题,因为 NodeJS 事件循环被 Typeorm 的所有合并操作阻塞。

      似乎 Typeorm 对实体引用的对象实例做了一些事情,它递归地通过它们或类似的东西。

      我通过做两件事解决了这个问题:像你一样用新实体替换 create() 并用 insert 替换 save。 原文:

      let entity = man.create(Entity, {
        prop1: "something",
        prop2: 42,
        ref1: someOtherEntityInstance
      };
      entity = await man.save(Entity, entity); // set ID of new created entity
      
      // ...
      let anotherEntity = man.create(AnotherEntity, {
        ref2: entity,
        prop3: true,
      };
      anotherEntity = await man.save(Entity, entity);
      

      适合我的版本

      const entity = new Entity();
      entity.prop1 = "something";
      entity.prop2 = 42;
      entity.ref1 = new SomeOtherEntity();
      entity.ref1.id = someOtherEntityInstance.id;
      
      let insertInfo = await man.insert(Entity, entity);
      entity.id = (insertInfo.identifiers[0] as { id: number }).id;
      
      const anotherEntity = new AnotherEntity();
      anotherEntity.prop3 = true;
      anotherEntity.ref2 = new Entity();
      anotherEntity.ref2.id = entity.id;
      
      insertInfo = await man.insert(Entity, entity);
      anotherEntity.id = (insertInfo.identifiers[0] as { id: number }).id;
      

      使代码更难看,但现在运行没有任何问题。

      【讨论】:

      • 是的,我在他们的代码中发现了这个问题,解决它的另一个选项是:let anotherEntity = man.create(AnotherEntity, { ref2Id: entity.id, prop3: true, };跨度>
      猜你喜欢
      • 2012-03-19
      • 1970-01-01
      • 2015-04-24
      • 1970-01-01
      • 2015-05-22
      • 1970-01-01
      • 2017-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多