2012-08-24 25 views
2

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

通过对查询的检查,两个select查询是不同的,第一个查询得到很多东西,并且由它们执行的选择很简单。

下面是示例代码:

  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" 

我想保存的方法来识别它已经在内存中的对象,它并不需要再次得到它。 ...如果这是可能的...

回答

5

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

他们选择以这种方式设计ORM的原因,首先是他们看着你的对象,看它是否目前有一个ID。如果是这样,他们会执行SELECT以确保它确实存在于数据库中。如果是,则执行更新。如果记录不存在,则执行INSERT。你可以通过创建对象来测试,然后从数据库中手动删除行,而不需要django知道。然后致电save()

这是如何工作,以确保Django保持一致性。

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

+0

我已经做了使用tracelytics.com跟踪和最有趣的部分是第二个查询需要大约1ms的每个查询。所以它非常快,但它确实为这个特定视图增加了1秒。但是现在它确实很有意义。谢谢。 –

+0

您的意思是说您的视图正在进行1000次更新,这意味着存在1秒的检查? – jdi

+0

是的,这是正确的。 –