Django预取相关并存在

Posted

技术标签:

【中文标题】Django预取相关并存在【英文标题】:Django prefetch related and exists 【发布时间】:2018-11-11 13:25:18 【问题描述】:

我在查询具有多个 m2m 关系的模型时使用prefetch_related

qs = context.mymodel_set.prefetch_related('things1', 'things2', 'things3')

所以当我这样做时不需要执行额外的查询来获取things1,它们应该已经被获取了:

r = list(qs)
r[0].things1.all()

但是如果我使用r[0].things1.exists() 会怎样?这会生成一个新的查询吗?还是会使用预取的信息?如果它生成一个新查询,这是否意味着为存在检查而使用r[0].things1.all() 更有效?

PS:缓存信息与数据库不同步并不让我担心这个特定问题。

【问题讨论】:

【参考方案1】:

为自己check the queries that Django is running 很容易。

当我尝试它时,似乎obj.things.exists() 在预取things 时没有引起任何额外的查询。

【讨论】:

我正在使用shell_plus --print-sql 进行测试,r[0].things1.all() 似乎正在查询数据库。但是当我做r[0].things1.exists() 时,什么都没有打印出来。 看来我错了 - 当 things 被预取时,exists() 似乎不会引起额外的查询。你的r[0].things.all() 不应该引起任何额外的查询——这就是预取的重点。您还没有显示查询是什么——也许您的 __str__ 方法会导致外键查找。

以上是关于Django预取相关并存在的主要内容,如果未能解决你的问题,请参考以下文章

通过预取提高性能并选择相关

教义 orm:绕过延迟加载并在 getter 中预取相关记录

分布式缓存和预取相关的有趣的链接

如何使用 prefetch_related 获取 Django 相关模型中的最新位置

Django prefetch_related 与限制

如何测量Haswell微架构的后期预取和杀死预取?