有一个Foo
模型,其中有一个ForeignKey字段bar
:
class Foo(models.Model):
...
bar = models.ManyToManyField('bar.Bar', related_name='some_bar')
...
另外Foo
具有get_config()
方法,该方法返回其包含bar
的字段,如:
def get_config(self):
return {
...
'bar': map(lambda x: x.get_config(), self.bar.all())
...
现在数据库中有10,000行Foo
。也有一些Bar
行。
尝试检索大约10,000 Foo
的数据,包括嵌套的Bar
数据:
query = Foo.objects.all().prefetch_related('bar')
return [obj.get_config() for obj in query]
查询执行大约6秒钟。如果没有bar
字段-仅400毫秒。
预取似乎不能完全起作用bar.get_config()
似乎在每个迭代步骤中都命中数据库。应该只加载一次所有Bar
对象一次,然后从该条查询中获取配置以填充每个foo
配置。
如果在iterator()
循环中使用for
,则通话几乎停顿并花费数十秒:[obj.get_config() for obj in query.iterator()]
答案 0 :(得分:0)
prefetch_related
正在工作。 Django使用包含WHERE子句和所有Bar
中的ids
的单个SELECT预取Foo
。这个具有10k id的SELECT比10k SELECTS快得多,但比没有过滤器的单个SELECT慢得多。