上午建立了一項服務,需要維護一些案例跟蹤系統。這裏是我們的模型:django查詢具有多個外鍵的模型的性能?
class Incident(models.Model):
title = models.CharField(max_length=128)
category = models.ForeignKey(Category)
status = models.ForeignKey(Status)
severity = models.ForeignKey(Severity)
owned_by = models.ForeignKey(User, related_name="owned_by", null=True, blank=True)
next_action = models.ForeignKey(IncidentAction)
created_date = models.DateTimeField()
created_by = models.ForeignKey(User, related_name="opened_by")
last_edit_date = models.DateTimeField(null=True, blank=True)
last_edit_by = models.ForeignKey(User, related_name="last_edit_by", null=True, blank=True)
closed_date = models.DateTimeField(null=True, blank=True)
closed_by = models.ForeignKey(User, related_name="Closed by", null=True, blank=True)
因爲有很多外鍵被拉進這個模型,它會引起有趣的sql查詢。我們一直在使用djblets data grid和django調試工具欄作爲試用版,並且在每次爲使用外鍵的視圖添加新列時都會遇到大量查詢時感到震驚,它基本上實現了這種類型的查詢工作流:
#prepare the grid
select * from incident_table;
#render each row
for each row in incident table
for each column that is a foreign key select row from foreign table with id
它做一個額外的選擇查詢每一行,試圖拉屬性的外鍵的每一列。
我在想這是django及其ORM關於從外鍵模型拉入屬性的普遍問題。作爲測試,我放棄了數據網格,併爲查詢集做了一個簡單的屬性列表,並以類似的方式看到查詢膨脹起來。
我們希望通過大量的用戶訪問模型來擴展這個範圍。作爲比較,我在User模型中做了一個類似的視圖,它的完整顯示只是使用一個查詢完成的,因爲如果您只從給定模型中拖出字段,則不會爲每個額外列創建額外的數據庫命中。
我們嘗試了一些優化爲:
- django-orm-cache:似乎並不
- django-caching使用Django 1.0.4工作:這非常適用於高速緩存經常查詢模型
- 視圖級緩存與memcached
- 編輯:使用select_related()可以通過沒有往返回數據庫的方式來加速模板渲染,但它看起來好像它遵循外鍵只是一個使用每個外鍵的單個查詢的原始查詢集的時間頭。似乎提前提出了多數據庫查詢命中。
但也有我們正在徵求羣衆的智慧上的一些更深層的問題:與國外萬噸鍵
- 對於模型是什麼讓它有效地查詢以獲得性能的最佳方式來自外鍵?
- 是否緩存依賴模型是使用上述ORM緩存系統的唯一方法?
- 或者這是一個超過ORM的標準情況,需要使用連接來滾動我們自己的自定義sql查詢以儘可能高效地獲得所需的數據網格輸出?
DB/performance: layout of django model that rarely refers to its parent more than once, Django ORM: caching and manipulating ForeignKey objects:
,所提出的緩存和關注外鍵關聯的問題
啊,是的。我站在非常糾正 - 看起來像datagrid實際上忽略提供的查詢集提供的任何優化,並執行其自己的查找。使用您的示例對我的模型進行獨立測試,使得select_related()的優勢如日清晰。謝謝! – dmyung 2009-12-29 19:23:32