2013-01-15 23 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;

当人们说通用外键有性能损失时,他们引用了这个查询开销。

只有非常狭窄的情况下,你真的想使用通用的外键。上面链接的文章也讨论了这些。