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 查询问题的主要内容,如果未能解决你的问题,请参考以下文章