在 Django 文档中,
select_related()
“遵循”外键关系,在执行查询时选择其他相关对象数据。
prefetch_related()
对每个关系进行单独查找,并在 Python 中进行“连接”。
“在 python 中加入”是什么意思?有人可以举例说明吗?
我的理解是,对于外键关系,使用 select_related
;对于 M2M 关系,使用 prefetch_related
。这个对吗?
原文由 NeoWang 发布,翻译遵循 CC BY-SA 4.0 许可协议
你的理解大部分是正确的。当您要选择的对象是单个对象时,您使用
select_related
,因此OneToOneField
或ForeignKey
。你使用prefetch_related
当你要得到一组“东西”时,所以ManyToManyField
如你所说或相反ForeignKey
只是为了澄清我所说的“反向ForeignKey
s”的意思,这是一个例子:不同之处在于
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 中的对象有相当多的内存开销,这也是一个考虑因素。