当前位置: 首页 > 知识库问答 >
问题:

在Django ORM中select_related和prefetch_related之间有什么区别?

严朝明
2023-03-14

在Django doc,

select_related()“跟随”外键关系,在执行查询时选择其他相关对象数据。

我的理解是,对于外键关系,使用select_related;对于M2M关系,请使用prefetch_related。这是正确的吗?

共有1个答案

邢良才
2023-03-14

你的理解大体上是正确的。如果要选择的对象是单个对象,则使用select_related,因此使用OneTooneFieldForeignKey。当您要获取一个“集合”时,您可以使用prefetch_related,因此manytomanyfield如您所述,或者将foreignkey反向。为了澄清“reverseforeignkeys”是什么意思,这里有一个示例

class ModelA(models.Model):
    pass

class ModelB(models.Model):
    a = ForeignKey(ModelA)

ModelB.objects.select_related('a').all() # Forward ForeignKey relationship
ModelA.objects.prefetch_related('modelb_set').all() # Reverse ForeignKey relationship

不同的是,select_related执行SQL联接,因此从SQL Server将结果作为表的一部分返回。另一方面,prefetch_related执行另一个查询,因此减少了原始对象中的冗余列(上例中为modela)。对于可以使用select_related的任何内容,都可以使用prefetch_related

折衷之处是prefetch_related必须创建一个ID列表并将其发送回服务器,这可能需要一段时间。我不确定是否有一个很好的方法在一个事务中这样做,但我的理解是Django总是发送一个列表,并说SELECT...在那里pk(...,...)基本上是。在这种情况下,如果预取的数据是稀疏的(比方说链接到人的地址的美国状态对象),这可能是非常好的,但是,如果它更接近于一对一,这可能会浪费大量的通信。如果有疑问,两个都试试,看看哪一个表现更好。

上面讨论的所有内容基本上都是关于与数据库的通信。然而,在Python方面,prefetch_related有一个额外的好处,即使用一个对象来表示数据库中的每个对象。使用select_related将在Python中为每个“父”对象创建重复的对象。由于Python中的对象具有相当大的内存开销,这也是一个考虑因素。

 类似资料:
  • 问题内容: 在Django文档中, “遵循”外键关系,在执行查询时选择其他相关对象数据。 对每个关系进行单独的查找,并在Python中执行“联接”。 “在python中进行连接”是什么意思?有人可以举例说明吗? 我的理解是,对于外键关系,使用; 对于M2M关系,请使用。它是否正确? 问题答案: 你的理解基本上是正确的。你可以使用select_related时,你将要选择的对象是一个对象,所以One

  • 问题内容: 在此示例中: 无法编译为: 而被编译器接受。 这个答案说明唯一的区别是,与不同,它允许您稍后引用类型,似乎并非如此。 是什么区别,并在这种情况下,为什么不第一编译? 问题答案: 通过使用以下签名定义方法: 并像这样调用它: 在jls§8.1.2中,我们发现(有趣的部分被我加粗了): 通用类声明定义了一组参数化类型(第4.5节), 每种可能通过类型arguments调用类型参数节的类型

  • 问题内容: 我是AngularJS的新手。谁能解释一下这些AngularJS运算符之间的区别:用适当的示例隔离范围时。 问题答案: 允许将在指令属性上定义的值传递到指令的隔离范围。该值可以是简单的字符串值(),也可以是带有嵌入式表达式()的AngularJS插值字符串。将其视为从父作用域到子指令的“单向”通信。 允许指令的隔离范围将值传递到父范围中,以便在属性中定义的表达式中进行求值。请注意,指令

  • 我看了Facebook的留档(React.Component),它提到了如何在客户端/服务器上调用,而仅在客户端上调用。对服务器做什么?

  • 我对Keras中的和感到困惑。他们之间有什么区别?我认为第一个是一个层,第二个是一个后端函数,但这意味着什么?在Conv2D中,我们发送过滤器的数量、过滤器的大小和跨步(但是在Conv2D中,我们使用内核是什么(64,3,3),我们把过滤器的数量和大小放在一起?我应该在哪里输入内核数?你能帮我解决这个问题吗?非常感谢。 pytorch中的代码 Keras中已更改的代码 但当我执行代码时,它会产生以

  • 在Eclipse中,modulepath和classpath之间有什么区别,我应该使用哪一个在lib文件夹中添加一个jar?为什么JRE系统库会出现在ModulePath中?