2

在我的应用程序中优化查询的过程中,我注意到了一些奇怪的事情。在给定的代码部分中,我将获取对象,更新一些值,然后保存。理论上,这应该执行 2 个查询。但实际上它执行了 3 个查询。1 获取对象时选择查询,2 保存对象时选择查询(另一个选择然后更新!)。删除一个查询可能看起来很愚蠢。在这个特定的方法中,我更新了许多对象,因此我保存的每个查询对数据库的命中减少了 1 次,并且应该加快该方法的速度。

通过检查查询,两个选择查询不同,第一个得到很多东西,执行的选择很简单。

这是示例代码:

            myobject = room.myobjects.get(id=myobject_id) # one query executed here
            myobject.color = color
            myobject.shape = shape
            myobject.place = place
            myobject.save() # two queries executed here

查询:

   1) "SELECT `rooms_object`.`id`, `rooms_object`.`room_id`, ......FROM `rooms_object` WHERE (`rooms_object`.`id` = %s AND `rooms_object`.`room_id` = %s )"

   2) "SELECT (1) AS `a` FROM `rooms_object` WHERE `rooms_object`.`id` = %s LIMIT 1"

   3) "UPDATE ......this ones obvious"

我希望保存方法能够识别它已经在内存中拥有该对象,并且不需要再次获取它......如果这甚至可能......

4

2 回答 2

6

第二个查询实际上并没有再次拉下对象。id它在执行查询之前对“存在”进行了极快的检查UPDATE。从该查询返回的所有内容都是一个1,并且该字段已编入索引,因此它应该非常有效。

他们选择以这种方式设计 ORM 的原因是,他们首先查看您的对象以查看它当前是否具有 ID。如果是这样,他们会SELECT确保它确实仍然存在于数据库中。如果是,他们执行更新。如果不知何故该记录不存在,他们将执行INSERT. 您可以通过创建对象来测试这一点,然后在 django 不知道的情况下从数据库中手动删除该行。然后打电话save()

这就是确保 django 保持一致性的工作方式。

如果它是一个新对象,您只会得到一个INSERT查询,因为它知道该对象现在没有id

于 2012-08-24T22:28:19.923 回答
3

这是通过 force_update 参数管理的

Model.save([force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS, update_fields=None])

将 force_update 设置为 True 以禁用存在检查(“SELECT (1) AS aFROM...”)。

https://docs.djangoproject.com/en/dev/ref/models/instances/

于 2013-08-09T16:49:51.283 回答