2012-08-24 58 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

是的,這是正確的。 –