2011-03-24 92 views
11

在與同行討論N + 1以及嚴重的數據庫查詢性能問題後,我訪問了http://guides.rubyonrails.org/active_record_querying.htmlDjango N + 1查詢解決方案

的ActiveRecord(導軌):

clients = Client.includes(:address).limit(10) 

如果客戶有地址,我打算訪問它們,同時通過客戶端循環,Rails提供includes,讓它知道先走,並把它們添加到查詢,從而消除了9次查詢。

Django的:

https://github.com/lilspikey/django-batch-select提供批量查詢的支持。你知道其他圖書館或技巧來實現上面Rails提供的,但是在一個不太冗長的莊園中(就像19個字符修復N + 1並且非常清晰的rails例子)?另外,批處理選擇是以同樣的方式解決問題還是這兩個不同的東西?

順便說一句,我沒有問關於select_related,雖然它可能乍一看似乎是答案。我正在談到addressclient有一個外鍵的情況。

回答

9

不幸的是,Django的ORM還沒有辦法做到這一點。

幸運的是,只需要2個查詢就可以完成它,只需要在Python中完成一些工作即可。

clients = list(Client.objects.all()[:10]) 
addresses = dict((x.client_id, x) for x in 
    Address.objects.filter(client__in=clients)) 
for client in clients: 
    print client, addresses[client.id] 
+0

謝謝。順便說一句,這將創建一個查詢的效率(即,Rails可能做什麼神奇的提供更好的性能,或者他們可能只是語法糖爲同一事物)?顯然,如果所有事情都不需要馬上評估,那麼它會更好,但也許他們也是這樣做的。 – orokusaki 2011-03-24 18:26:07

+0

我不知道。它*可以在一個查詢中執行動作,但這需要Django的ORM還沒有的一定程度的欺騙。 – 2011-03-24 18:28:12

+0

好的。再次感謝。 – orokusaki 2011-03-24 18:29:12

2

django-batch-select應該提供這個問題的答案,雖然我還沒有嘗試過。伊格納西奧的回答對我來說似乎是最好的。