2015-09-30 37 views
0

說我有三個Django模型:在查詢參數中使用關係還是在Django模型中使用模型屬性查找更快?

  • User
  • Staff這是一個對一個與User
  • Thing這是許多到一個與Staff在「所有者」字段。

使用MySQL數據庫,哪些性能更​​好?

Thing.objects.filter(owner=user.staff) # A 
Thing.objects.filter(owner__user=user) # B 

那麼如果我檢查,我想ThingUser擁有:

try: 
    Thing.objects.get(id=some_id, owner=user.staff) # D 
    Thing.objects.get(id=some_id, owner__user=user) # E 
except Thing.DoesNotExist: 
    return None 
else: 
    pass # do stuff 

# Or F: 
thing = Thing.objects.get(id=some_id) 
if thing.owner.user != user: 
    return None 
pass # do stuff 
+1

你應該嘗試django調試工具欄或分析你的代碼.. – Sayse

回答

1

這很大程度上取決於您如何獲得原始對象以及您之後完成的任務。如果您已經訪問了user.staff,或者您最初使用select_related查詢了用戶,則第一個查詢會更好,因爲它是一個表上的簡單SELECT,而第二個查詢會執行JOIN以訪問用戶表。

但是,如果您還沒有訪問user.staff,並沒有通過select_related最初得到它,第一個表達式將導致user.staff進行評估,這將觸發一個單獨的查詢,甚至之前做的事情查找。因此,在這種情況下,第二個查詢將更可取,因爲使用JOIN的單個查詢優於兩個簡單查詢。

但請注意,這幾乎肯定是一個微型優化,對整體運行時間幾乎沒有影響。

1

這兩項查詢可能最終一樣SQL,依賴於你的設置,型號,索引和數據庫驅動。您可以使用.query成員變量來驗證。如果他們不同,唯一真正的考驗將是經驗性的。我可以推薦django-devserveripython作爲性能分析工具。

1
Thing.objects.filter(owner=user.staff) # A 
Thing.objects.filter(owner__user=user) # B 

認爲第二一個是 「更好」。假設您從請求中獲得了用戶記錄:

  • B將僅在Thing上生成1個SQL查詢。
  • 我想A會爲user.staff生成一個查詢,然後生成一個關於Thing的查詢。 (也可能需要更多的內存,爲員工實例)

可以肯定的嘗試這一點,並檢查計時,並與調試工具欄生成的查詢:

for i in range(0, 100): 
    things = Thing.objects.filter(owner=user.staff) # A 
    #things = Thing.objects.filter(owner__user=user) # B 

    # that will execute the queries 
    for thing in things.all(): 
     print thing.name 

然後爲B代替...