【问题标题】:Django Generic Foreign keys - Good or Bad considering the SQL performance?Django Generic Foreign keys - 考虑到 SQL 性能是好是坏?
【发布时间】:2012-12-29 07:10:54
【问题描述】:

我有一个模型 A,它包含一个通用外键关系,在同一个应用程序中限制选择 3 个其他模型(将它们视为 BCD)。而且我知道我们不能使用filterget 或任何其他查询集操作的通用外键的局限性。

所以要实现这样的目标,A.objects.filter(generic_object__name="foo") 我必须首先过滤 B、C 和 D 的对象作为查询集,遍历它们并使用通用反向关系将 A 对象作为列表(不是查询集)。

我不确定它将如何影响数据库上的 SQL 性能,因为查询不是直接的。

PS:我需要使用通用外键,所以请提出任何 SQL 改进建议,而不是重新设计模型。

使用 Django 1.4.3 和 Postgres。

【问题讨论】:

标签: django performance postgresql foreign-key-relationship


【解决方案1】:

我想引用 David Cramer 的话:Disqus 的开发者,Django 的提交者

通用关系很好。它们并不慢,只是在您的代码库中更难管理。

我看到很多人告诉别人不要使用泛型关系,因为它很慢,但从来没有告诉过它有多慢。

【讨论】:

  • 确实如此。但我同意difficult to manage code base
  • 这是Source
  • 从通用外键切换似乎给了我一个加速(抱歉,手头没有数字) - 也避免了 OPs 问题中的问题。有趣的是,上面链接的来源quora.com/What-are-the-best-ways-to-improve-Django-performance 有相互矛盾的意见
  • 我应该注意 - 我放弃了 GFK 以避免 OP 遇到的确切问题 - 很难通过关系进行前向查询(虽然,反向很容易)
  • 进一步说明 - 我使用“连接对象/表” - 目前没有使用多对多,但可能应该使用!
【解决方案2】:

Avoid Django's GenericForeignKey 对通用外键(或“多态关联”,他们在 rails-speak 中称它们)中涉及的数据库设计反模式有很好而全面的描述。

就性能而言,每次您想从模型中检索相关的 GenericForeignKey 资源时,都需要 3 次数据库查询:

  1. SELECT object_id_field, object_id from myapp_a WHERE id=1;
  2. 从 django_content_type 选择 app_label,模型,其中 id=A.object_type_field;
    • 在应用程序代码中,计算表名model + _ + app_label
  3. SELECT A.object_id_field FROM TABLE_NAME;

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

只有极少数情况下您真正想要使用通用外键。上面链接的文章也讨论了这些。

【讨论】:

  • 有没有更好的方法来避免在 django 中使用通用外键?
  • @khadimhusen 有很多选择。最简单的方法是在模型中添加多个可为空的 ForeignKey 字段,并使用应用程序逻辑确保仅填充一个(例如覆盖模型的 save())。
【解决方案3】:

为您的模型添加一个 index_together 元选项:

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

【讨论】:

  • 这个答案到底是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多