原则实体删除与删除查询,性能比较
在使用学说时,我注意到,要删除一个实体,我需要通过给定的参数(名称,id等)检索该实体,然后调用 remove 方法。另一方面,在查询中,我可以只执行删除查询。
所以,似乎使用ORM风格需要两个操作,而一般的sql操作需要一个操作。这就是为什么,我有点困惑,我们是否应该在ORM中使用删除(或更新)操作?性能不是更差吗?或者我还有什么遗漏的吗?它能以ORM风格以任何其他方式完成吗?
在使用学说时,我注意到,要删除一个实体,我需要通过给定的参数(名称,id等)检索该实体,然后调用 remove 方法。另一方面,在查询中,我可以只执行删除查询。
所以,似乎使用ORM风格需要两个操作,而一般的sql操作需要一个操作。这就是为什么,我有点困惑,我们是否应该在ORM中使用删除(或更新)操作?性能不是更差吗?或者我还有什么遗漏的吗?它能以ORM风格以任何其他方式完成吗?
在 Doctrine2 中,您可以对代理对象调用 delete,该代理对象不是从数据库中加载的。只需创建一个“虚拟”对象,如下所示:
$user = $em->getPartialReference('model\User', array('id' => $id));
$em->remove($user);
它不需要初始查询,但我不太确定 Doctrine 是否仍然在刷新时在内部执行此操作。我没有在 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();