django可以在评估的查询集上使用prefetch_related而无需重做初始查询

时间:2015-09-23 14:42:11

标签: django performance orm django-queryset

考虑这段代码

users = UserProfile.objects.all()[:10]
# evaluate the query set
users_list = list(users)

users = users.prefetch_related('posts')

我想知道在评估后在queryset上使用prefetch_related会重复查询UserProfile模型。 感谢。

3 个答案:

答案 0 :(得分:1)

没有。直到你再次评估它,因为它不能神奇地从数据库中提取额外的数据。

>>> from django.db import connection
>>> from app.models import Foo
>>> bar = Foo.objects.all()[:1]
>>> len(connection.queries)
0
>>> bar_list = list(bar)
>>> len(connection.queries)
1
>>> bar = bar.prefetch_related('thing')
>>> len(connection.queries)
1
>>> bar_list = list(bar)
>>> len(connection.queries)
2

答案 1 :(得分:0)

不,在这种情况下,只有在调用变量users时才会查询查询。

print users

点击:

(0.000) QUERY = 'SELECT “userprofile"."id" INNER JOIN “posts" ON ( “userprofile"."usuari...

答案 2 :(得分:0)

正如here所解释的那样,QuerySet API在您第一次迭代它时执行数据库查询。在您的情况下,迭代发生的原因是list(users)

如果您在执行前调用它,prefetch_related函数会对第一个查询产生影响。

因此,这意味着:是的,您可以在迭代后调用prefetch_related,但QuerySet必须执行新的数据库查询以获取有关帖子的缺失信息。 QuerySets are cloned every time您调用prefetch_related之类的函数。因此,下一次迭代是克隆对象的第一次迭代。