2013-01-15 25 views
5

我有一個模型A其中包含一個通用的外鍵關係與限制選擇3個其他模型(認爲它們是B,CD)在同一個應用程序。我知道我們不能使用filterget或任何其他查詢集操作的泛型外鍵的侷限性。Django通用外鍵 - 考慮SQL性能的好還是壞?

所以要實現這樣的事情,我必須首先篩選B,C和D的對象作爲queryset,遍歷它們並使用通用的反向關係來獲取A對象作爲列表(而不是queryset)。

我不確定它會如何影響數據庫的SQL性能,因爲查詢不是直接的。 PS:我需要使用泛型的外鍵,所以請爲任何SQL改進建議,而不是重新設計模型。

使用Django 1.4.3和Postgres。

+0

什麼是「通用」外鍵? –

+0

我使用了與此處所述相同的設置,https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1 – Babu

回答

7

我想引述大衛·克拉默一些話:Disqus的開發商,Django的commiter

通用的關係都很好。它們不是很慢,在您的代碼庫中更難以管理。

我看到很多人告訴別人不使用泛型關係,因爲它很慢,但從不知道它是如何慢。

+0

這是真的。但我同意'難以管理的代碼庫' – Babu

+2

這裏是[源代碼](http://www.quora.com/What-are-the-best-ways-to-improve-django-performance) –

+0

@ ChrisVilla謝謝! – L42y

0

添加index_together元選項,你的模型:

class Meta: 
    index_together = [('cprofile_id', 'cprofile_type')] 
1

Avoid Django's GenericForeignKey有參與通用外鍵(或數據庫設計反模式的一個很好的和全面的描述「多態關聯,」他們叫他們在軌道-說話)。

至於性能方面,它需要3數據庫查詢你想從你的模型中檢索相關GenericForeignKey資源每次:

  1. 選擇object_id_field,OBJECT_ID從myapp_a WHERE ID = 1;
  2. SELECT app_label,model FROM django_content_type WHERE id = A.object_type_field;
    • 在應用程序代碼,計算表名model + _ + app_label
  3. SELECT A.object_id_field FROM TABLE_NAME;

當人們說通用外鍵有性能損失時,他們引用了這個查詢開銷。

只有非常狹窄的情況下,你真的想使用通用的外鍵。上面鏈接的文章也討論了這些。