为什么迭代大型 Django QuerySet 会消耗大量内存?

2023-11-29

该表包含大约一千万行。

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

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

我也尝试过Event.objects.iterator()其行为方式相同。

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

我误解了什么?

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


Nate C 很接近,但还不够。

From the docs:

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

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

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

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

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

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

  • 内存高效的 Django QuerySet 迭代器
  • 批量查询集
  • 查询集foreach
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么迭代大型 Django QuerySet 会消耗大量内存? 的相关文章

随机推荐