本站消息

  出租广告位,需要合作请联系站长

  今日名言-想象你自己对困难作出的反应,不是逃避或绕开它们,而是面对它们,同它们打交道,以一种进取的和明智的方式同它们奋斗 。——马克斯威尔·马尔兹

  今日名言-用谅解、宽恕的目光和心理看人、待人。人就会觉得葱笼的世界里,春意盎然,到处充满温暖。——蔡文甫


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

为什么遍历大型 Django QuerySet 会消耗大量内存?

发布于2021-07-24 21:18     阅读(1088)     评论(0)     点赞(3)     收藏(0)


有问题的表包含大约一千万行。

for event in Event.objects.all():
    print event

这会导致内存使用量稳步增加到 4 GB 左右,此时行会快速打印。打印第一行之前的漫长延迟让我感到惊讶 - 我预计它几乎可以立即打印。

我也试过Event.objects.iterator()哪个表现相同。

我不明白 Django 正在将什么加载到内存中,或者为什么要这样做。我希望 Django 在数据库级别遍历结果,这意味着结果将以大致恒定的速率打印(而不是在漫长的等待后一次全部打印)。

我误解了什么?

(我不知道它是否相关,但我正在使用 PostgreSQL。)


解决方案


Nate C 很接近,但不完全。

文档

您可以通过以下方式评估 QuerySet:

  • 迭代。QuerySet 是可迭代的,它会在您第一次对其进行迭代时执行其数据库查询。例如,这将打印数据库中所有条目的标题:

    for e in Entry.objects.all():
        print e.headline
    

因此,当您第一次进入该循环并获取查询集的迭代形式时,将一次性检索您的一千万行。您所经历的等待是 Django 加载数据库行并为每个行创建对象,然后返回您可以实际迭代的内容。然后您将所有内容都保存在内存中,结果就会溢出。

从我对文档的阅读来看,iterator()无非是绕过 QuerySet 的内部缓存机制。我认为逐一执行可能有意义,但相反,这将需要对您的数据库进行 1000 万次单独点击。也许并不是那么理想。

有效地迭代大型数据集是我们还没有完全正确的事情,但是有一些片段您可能会发现对您的目的有用:



所属网站分类: 技术文章 > 问答

作者:官方问答小能手

链接:http://www.pythonpdf.com/blog/article/242/694fe9b2e5569f48754e/

来源:编程知识网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

3 0
收藏该文
已收藏

评论内容:(最多支持255个字符)