php Doctrine entity remove vs delete查询,性能对比

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11486662/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 00:38:25  来源:igfitidea点击:

Doctrine entity remove vs delete query, performance comparison

phpperformancedoctrine

提问by Rana

While using doctrine, I noticed that, to delete an entity, I need to retrieve that entity by given parameter(name,id etc) and then call the remove method. On the other hand, in query, I can just execute delete query.

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

So, seems like, using ORM style requires two operation and general sql operation require one operation. That's why, I am a little confusing, whether we should use delete(or update) operation in ORM? Isn't it worse in performance? Or Is there anything else I am missing? Can it be done in any other way in ORM style?

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

回答by ZolaKt

In Doctrine2 you can call the delete on a proxy object, which is not loaded from the database. Just create a "dummy" object, something like:

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

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

It doesn't require the initial query, but I'm not quite sure if Doctrine still does it internally on flush. I don't see it in the SqlLog.

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

Just to add, I think this is expected behavior of any decent ORM. It deals with objects and relations. It has to know that something exists before deleting it. ORM is not just a query generator. Generally, a native query will always be faster in any ORM. Any ORM adds a layer of abstraction and it takes some time to execute it. It is a typical tradeoff, you get some fancy features and clean code, but loose some on performance.

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

EDIT:

编辑:

I'm glad it worked out for you. Actually I stumbled on another problem, which made me realize that proxies and partial objects aren't actually the same thing. Partial objects instance the real model class, and fill it with values you want. After you initialize a partial object lazy-loading doesn't work on it anymore. So for instance, if you make a partial object with only the id, and want to delete only if another object field satisfies some condition, it will not work, because that other field will always be null.

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

On the other hand, proxies do work with lazy-loading, and don't share the problems that partial objects have. So I would strongly suggest not to use getPartialReferencemethod, instead you can do something like:

另一方面,代理确实与延迟加载一起工作,并且不具有部分对象所具有的问题。所以我强烈建议不要使用getPartialReference方法,而是可以执行以下操作:

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

The getReferencemethod returns the object if it is already loaded or a proxy if it is not. A proxy can lazy-load all the other values if/when you need them. As for your example, they will behave exactly the same, but proxies are surely a better way to go.

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

回答by Estefanio NS

Done! for me it worked like this add line 3:

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

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