条令实体删除与删除查询,性能比较


Doctrine entity remove vs delete query, performance comparison

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

因此,使用ORM样式需要两个操作,而一般的sql操作需要一个操作。这就是为什么,我有点困惑,我们是否应该在ORM中使用删除(或更新)操作?它的表现不是更差吗?或者我还缺少什么吗?在ORM风格中,它可以以任何其他方式完成吗?

在Doctrine2中,您可以对代理对象调用delete,该对象不是从数据库加载的。只需创建一个"伪"对象,类似于:

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

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

只是想补充一点,我认为这是任何体面的ORM的预期行为。它处理对象和关系。在删除它之前,它必须知道某些东西存在。ORM不仅仅是查询生成器。一般来说,本机查询在任何ORM中都会更快。任何ORM都会添加一层抽象,执行它需要一些时间。这是一个典型的折衷,你会得到一些花哨的功能和干净的代码,但在性能上会有所松动。

编辑:

我很高兴你成功了。事实上,我偶然发现了另一个问题,这让我意识到代理和部分对象实际上不是一回事。部分对象是真实模型类的实例,并用所需的值填充它。初始化一个部分对象之后,惰性加载就不再对它起作用了。因此,例如,如果您只创建一个id为的部分对象,并且仅在另一个对象字段满足某些条件时才希望删除,那么它将不起作用,因为另一个字段将始终为null。

另一方面,代理可以处理延迟加载,并且不共享部分对象所具有的问题。因此,我强烈建议不要使用getPartialReference方法,相反,您可以执行以下操作:

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

如果对象已加载,则getReference方法返回该对象;如果未加载,则返回代理。如果您需要,代理可以延迟加载所有其他值。就你的例子而言,他们的行为完全相同,但代理肯定是更好的选择。

完成!对我来说,它的工作原理是这样添加第3行:

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