Ego*_*ler 3 python mysql database django memory-management
我有一个相当大的数据库表(1M+ 行),在 Django 中过滤结果时遇到问题。
目前过滤逻辑如下:
results = Result.objects.filter(date__range=(date_from, date_to))
for result in results:
# do stuff
Run Code Online (Sandbox Code Playgroud)
在某些时期它会导致崩溃(可能是由于内存耗尽)
我想知道,用以下内容替换它会更有效:
results = Result.objects.all().order_by('-id')
for result in results:
if result.date > date_to:
continue
if result.date < date_from:
break
# do stuff
Run Code Online (Sandbox Code Playgroud)
理论上,由于 .all() 创建了一个惰性 QuerySet,它的性能可能比在 1M+ 行的数据库中进行范围过滤要好。了解两种情况下的内存消耗也会很有趣。
也许还有另一种解决方案如何更有效地在恒定内存中做到这一点?
谢谢!
理论上,由于
.all()创建了一个惰性 QuerySet,它可能比具有 100 万行以上的数据库中的范围过滤性能更好。了解两种情况下的内存消耗也会很有趣。
QuerySet 是惰性的,因为它只会在必要时检索对象,但一旦必须这样做,它将获取所有项目。.all()顺便说一下,不仅是惰性的,所有的 QuerySets 都是惰性的,所以如果你定义一个查询集Result.objects.filter(…),那QuerySet也是惰性的。
但是不管它是如何实现的,在数据库端过滤更有效,因为数据库就是为此而设计的,它导致从数据库到 Python/Django 层的带宽更少。
如果存在内存问题,这可能意味着您的QuerySet,即使经过过滤,也太大而无法存储在内存中。您可以使用.iterator(…)[Django-doc] 方法来加载可以处理的批量项目:
results = Result.objects.filter(date__range=(date_from, date_to)).iterator()
for result in results:
# …
passRun Code Online (Sandbox Code Playgroud)
如果每次都会将一大块记录加载到内存中,然后才能进行处理。如果您不存储项目(例如在列表中),那么 Python 可以为下一个块重用内存。
| 归档时间: |
|
| 查看次数: |
34 次 |
| 最近记录: |