gpt4 book ai didi

python - Django ORM 中的 select_related 和 prefetch_related 有什么区别?

转载 作者:IT老高 更新时间:2023-10-28 12:12:39 40 4
gpt4 key购买 nike

在 Django 文档中,

select_related() "follows" foreign-key relationships, selecting additional related-object data when it executes its query.

prefetch_related() does a separate lookup for each relationship, and does the "joining" in Python.

“在python中加入”是什么意思?谁能举例说明一下?

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

最佳答案

您的理解大部分是正确的。当您要选择的对象是单个对象时,您可以使用 select_related,例如 OneToOneFieldForeignKey。当您要获得一组“东西”时,您使用 prefetch_related,因此如您所说的 ManyToManyField 或反向 ForeignKey。只是为了澄清我所说的“反向 ForeignKeys”的意思,这里有一个例子:

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 服务器获取结果作为表的一部分。另一方面,prefetch_related 执行另一个查询,因此减少了原始对象中的冗余列(上例中的 ModelA)。您可以将 prefetch_related 用于您可以使用 select_related 的任何内容。

权衡是 prefetch_related 必须创建一个 ID 列表并将其发送回服务器,这可能需要一段时间。我不确定在事务中是否有这样做的好方法,但我的理解是 Django 总是只发送一个列表并说 SELECT ... WHERE pk IN (...,...,...)基本上。在这种情况下,如果预取的数据是稀疏的(假设美国国家对象链接到人们的地址),这可能非常好,但是如果它更接近一对一,这可能会浪费大量通信。如有疑问,请尝试两者,看看哪个效果更好。

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

关于python - Django ORM 中的 select_related 和 prefetch_related 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31237042/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com