Luc*_*ang 20 python django orm iterator django-queryset
这是来自queryset iterator()方法的django文档:
QuerySet通常在内部缓存其结果,以便重复的计算不会导致其他查询.相反,iterator()将直接读取结果,而不在QuerySet级别执行任何缓存(在内部,默认迭代器调用iterator()并缓存返回值).对于返回大量只需要访问一次的大量对象的QuerySet,这可以带来更好的性能并显着降低内存.
阅读之后,我仍然感到困惑:关于性能提升和内存减少的一线表明我们应该使用这种iterator()方法.有人可以提供一些好的和坏的案例iterator()使用的例子吗?
即使查询结果没有被缓存,如果他们真的想多次访问模型,有人只能做以下事情吗?
saved_queries = list(Model.objects.all().iterator())
Run Code Online (Sandbox Code Playgroud)
Ste*_*ven 29
请注意您调用的句子的第一部分:
For a QuerySet which returns a large number of objects that you only need to access once
因此,与此相反的是:如果您需要重复使用一组结果,并且它们不会导致内存问题那么多,那么您就不应该使用iterator.因为额外的数据库往返总是会降低您的性能而不是使用缓存的结果.
您可以强制将QuerySet计算到列表中,但是:
saved_queries = Model.objects.all()QuerySets是懒惰的,所以你可以有一个上下文处理器,例如,它将QuerySet放入每个请求的上下文中,但只在你在某些请求上访问它时才会被评估,但如果你强迫评估每次请求都会发生数据库命中 典型的Web应用程序案例适用于相对较小的结果集(它们必须及时交付给浏览器,因此如果需要,可以采用分页或类似技术来减少数据量)因此通常标准QuerySet行为就是您想要的.毫无疑问,您必须将QuerySet存储在变量中以获得缓存的好处.
好好利用迭代器:处理大量可用内存的处理结果(大量小对象或较少的大对象).根据我的经验,这通常是在进行大量数据处理时的管理命令.
小智 7
我同意史蒂文的观点,我想发表一下看法:
“它需要更多的输入,而不仅仅是 saving_queries = Model.objects.all()”。是的,但是有一个主要区别,为什么你应该使用 list(Model.objects.all())。让我给你举个例子,如果你把分配给一个变量,它将执行查询并将其保存在那里,让我们假设你有+1M记录,所以这意味着,你将在列表中拥有+1M记录您可能会或可能不会立即使用,所以我建议只使用史蒂文所说的,仅使用Model.objects.all(),因为这分配给一个变量,它不会执行,直到您调用该变量,从而节省您的数据库来电。
您应该使用 prefetch_lated() 来避免对数据库进行过多的调用,因此,它将使用 Django 反向查找来帮助您并节省大量时间。