Doctrine实体删除vs删除查询,性能比较 [英] Doctrine entity remove vs delete query, performance comparison

查看:641
本文介绍了Doctrine实体删除vs删除查询,性能比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

所以,好像,使用ORM风格需要两个操作和一般的sql操作需要一个操作。这就是为什么我有点混乱,我们是否应该在ORM中使用delete(或更新)操作?表现不是更糟吗?还有还有什么我失踪的吗?在ORM风格中可以以任何其他方式完成?

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?

推荐答案

在Doctrine2中,您可以在代理对象上调用delete没有从数据库加载。只需创建一个虚拟对象,如:

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:

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

它不需要初始查询,但是我不太清楚Doctrine是否仍然内部的 fush 。我没有看到它在SqlLog。

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

只是添加,我认为这是任何体面的ORM的预期行为。它处理对象和关系。它必须知道删除它之前存在某些东西。 ORM不仅仅是一个查询生成器。通常,任何ORM中的本机查询将始终更快。任何ORM都会添加一层抽象,需要一些时间来执行它。这是一个典型的折衷,你会得到一些奇特的功能和干净的代码,但松散一些表现。

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.

编辑:

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

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.

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

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 getPartialReference method, instead you can do something like:

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

getReference 方法返回对象,如果已经加载或代理,如果不是。如果需要,代理可以延迟加载所有其他值。对于你的例子,他们的行为是完全一样的,但代理人肯定是一个更好的方式。

The getReference method 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.

这篇关于Doctrine实体删除vs删除查询,性能比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆