【问题标题】:Doctrine entity remove vs delete query, performance comparisonDoctrine 实体删除 vs 删除查询,性能比较
【发布时间】:2012-07-14 06:13:04
【问题描述】:

在使用原则时,我注意到,要删除一个实体,我需要通过给定的参数(名称、id 等)检索该实体,然后调用 remove 方法。另一方面,在查询中,我可以只执行删除查询。

所以,看起来,使用 ORM 样式需要两次操作,而一般的 sql 操作需要一次操作。这就是为什么,我有点困惑,我们是否应该在 ORM 中使用删除(或更新)操作?性能不是更差吗?或者还有什么我想念的吗?可以用 ORM 风格以任何其他方式完成吗?

【问题讨论】:

    标签: php performance doctrine


    【解决方案1】:

    在 Doctrine2 中,您可以对未从数据库加载的代理对象调用删除。只需创建一个“虚拟”对象,例如:

    $user = $em->getPartialReference('model\User', array('id' => $id));
    $em->remove($user);
    

    它不需要初始查询,但我不太确定 Doctrine 是否仍然在 flush 内部执行此操作。我在 SqlLog 中没有看到它。

    补充一点,我认为这是任何体面的 ORM 的预期行为。它处理对象和关系。它必须在删除之前知道某些东西的存在。 ORM 不仅仅是一个查询生成器。通常,原生查询在任何 ORM 中总是更快。任何 ORM 都会增加一个抽象层,执行它需要一些时间。这是一个典型的权衡,你会得到一些花哨的功能和干净的代码,但会失去一些性能。

    编辑:

    我很高兴它对你有用。实际上我偶然发现了另一个问题,这让我意识到代理和部分对象实际上并不是一回事。部分对象实例化真实的模型类,并用您想要的值填充它。初始化部分对象后,延迟加载不再适用。因此,例如,如果您创建一个只有 id 的部分对象,并且仅在另一个对象字段满足某些条件时才想删除,它将不起作用,因为该其他字段将始终为空。

    另一方面,代理确实可以使用延迟加载,并且不会共享部分对象存在的问题。所以我强烈建议不要使用getPartialReference 方法,你可以这样做:

    $user = $em->getReference('model\User', $id);
    $em->remove($user);
    

    getReference 方法如果已经加载,则返回对象,否则返回代理。如果/当您需要它们时,代理可以延迟加载所有其他值。至于您的示例,它们的行为将完全相同,但代理肯定是更好的选择。

    【讨论】:

    • getReference 方法加载你的实体,如果这个实体有依赖/后代类(子类)。
    【解决方案2】:

    完成! 对我来说,它像这样添加第 3 行:

    $user = $em->getReference('model\User', $id);
    $em->remove($user);
    $em->flush();
    

    【讨论】:

      猜你喜欢
      • 2016-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-26
      • 1970-01-01
      相关资源
      最近更新 更多