Django,多态性和 N+1 查询问题

Posted

技术标签:

【中文标题】Django,多态性和 N+1 查询问题【英文标题】:Django, polymorphism and N+1 queries problem 【发布时间】:2011-08-02 11:56:09 【问题描述】:

我正在 Django 中编写一个应用程序,我想在使用 ForeignKeys 时利用隐式继承。就我而言,处理这个问题的唯一方法是使用 django_polymorphic 库(在 Django 中没有单表继承,WHY OH WHY??)。

我想了解此解决方案的性能影响。进行多态查询时执行什么样的连接?与常规查询相比,它是否必须多次访问数据库(臭名昭著的 N+1 查询问题)?文档警告说“现代 RDBM 无法有效处理所执行的查询类型”?但是,它并不能真正说明这些查询是什么。任何统计数据和经验都会很有帮助。

编辑:

是否有任何方法可以检索对象列表,每个对象都是其实际类的实例,具有恒定数量的查询?我以为这就是上述库的作用,但是现在我很困惑,我不再那么确定了。

【问题讨论】:

【参考方案1】:

在 Django 中,继承模型在内部通过 OneToOneField 表示。如果您在查询中使用select_related(),Django 将遵循一对一的关系向前和向后以包含引用的表和连接;因此,如果您使用select_related,则无需访问数据库两次。

【讨论】:

好吧,但在这里我想使用一个外部库,它尝试为关系中的所有项目返回实际类的实例。因此,我想它会对底层层次结构中的所有表执行一些额外的连接。这就是我所关心的。 AFAIK django-polymorphic-models 不使用select_related(),但是您应该能够在使用它检索查询集时添加它,因此您也不应该有任何额外的数据库调用。 .. 嗯...代码似乎基于这个 sn-p:djangosnippets.org/snippets/1034。不幸的是,它执行了 N+1 个查询,这在我的情况下是不可接受的。【参考方案2】:

好吧,我又挖了一点,发现了这个不错的段落:

https://github.com/bconstantin/django_polymorphic/blob/master/DOCS.rst#performance-considerations

很高兴这个库做了一些相当理智的事情。很高兴知道这一点。

【讨论】:

【参考方案3】:

Django-Typed-Models 是 Django-Polymorphic 的替代方案,它采用简单干净的方法来解决单表继承问题。它适用于添加到模型中的“类型”属性。当您保存它时,该类将保留在“类型”属性中。在查询时,该属性用于设置结果对象的类。

它可以按照您的期望进行查询(从查询集返回的每个对象都是向下转换的类),而不需要特殊的语法或与 Django-Polymorphic 相关的可怕代码量。并且没有额外的数据库查询。

【讨论】:

以上是关于Django,多态性和 N+1 查询问题的主要内容,如果未能解决你的问题,请参考以下文章

Django-多态模型在1.7上进行迁移时遇到问题

如何在 Django 中添加多态类?

使用 Django 多态模型生成 HTML

了解 C++ 中的继承和多态性

C++ 强制转换运算符重载和多态性

如何在 Hibernate 中执行非多态 HQL 查询?