有问题的表包含大约一千万行。
for event in Event.objects.all():
print event
这会导致内存使用量稳定增加到 4 GB 左右,此时行会快速打印。第一行打印之前的漫长延迟让我感到惊讶——我希望它几乎可以立即打印。
我还尝试了 Event.objects.iterator()
,它的行为方式相同。
我不明白 Django 将什么加载到内存中或为什么要这样做。我希望 Django 在数据库级别迭代结果,这意味着结果将以大致恒定的速率打印(而不是在漫长的等待后一次全部打印)。
我误解了什么?
(我不知道它是否相关,但我正在使用 PostgreSQL。)
最佳答案
Nate C 很接近,但不完全是。
来自 the docs :
You can evaluate a QuerySet in the following ways:
Iteration. A QuerySet is iterable, and it executes its database query the first time you iterate over it. For example, this will print the headline of all entries in the database:
for e in Entry.objects.all(): print e.headline
因此,当您第一次进入该循环并获取查询集的迭代形式时,您的一千万行将被一次性全部检索到。您经历的等待是 Django 加载数据库行并为每一行创建对象,然后返回您可以实际迭代的内容。然后您将所有内容都记在内存中,然后结果就会溢出来。
根据我对文档的阅读,iterator()
无非就是绕过 QuerySet 的内部缓存机制。我认为一件一件的事情对它来说可能是有意义的,但这反过来需要对你的数据库进行一千万次的单独点击。也许不是那么令人向往。
高效地迭代大型数据集是我们还没有完全做到的事情,但是您可能会发现其中的一些片段对您的目的有用:
关于sql - 为什么遍历大型 Django QuerySet 会消耗大量内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4222176/