Python 使用queryset从django获取百万记录速度较慢

Python 使用queryset从django获取百万记录速度较慢,python,django,postgresql,Python,Django,Postgresql,我想迭代表的所有对象(Post) 我正在使用以下代码: posts = Post.objects.all() for post in posts: process_post(post) process\u post是一个芹菜任务,它将在后台运行,并且不会更新post。但我遇到的问题是post表有100万条记录。这不是一次性作业。我每天都在运行它 for post in posts 在上面的一行中,调用Query,它一次从数据库中获取所有数据 如何提高其性能? 有什么方法可以批量获取数据

我想迭代表的所有对象(Post) 我正在使用以下代码:

posts = Post.objects.all()
for post in posts:
   process_post(post)
process\u post
是一个芹菜任务,它将在后台运行,并且不会更新post。但我遇到的问题是post表有100万条记录。这不是一次性作业。我每天都在运行它

for post in posts
在上面的一行中,调用Query,它一次从数据库中获取所有数据

如何提高其性能?
有什么方法可以批量获取数据吗?

我的第一个建议是使用与选择相关或与预取相关的方法。浏览django的文档并了解它,它会解决您的问题。但正如你所说的,你有数百万条记录。迭代这些将始终是一项成本高昂的业务。如果process\u post方法需要时间,最好的解决方案是使用存储过程。您只需向数据库发出一个请求即可实现目标,而不是循环中数百万个数据库调用。

创建自己的
迭代器。例如,假设
100万条记录

count = Post.objects.all().count() #1 million
chunk_size = 1000   
for i in range(0, count, chunk_size):
    posts = Post.objects.all()[i:i+chunk_size]
    for post in posts:
        process_post(post)        

在queryset上切片将播放
LIMIT
OFFSET
用法。查询可以根据
chunk\u size
的增加而减少,其中as内存使用也会增加。针对您的用例优化它。

过程\u post
更新方法吗?请使用。如果它仍然导致内存消耗过多,则可能需要考虑使用数据库侧游标。实际上,默认行为是加载所有内容。但是将行作为python对象加载是一个缓慢的过程,如果您只需要进行简单的处理,我建议您使用
values()
update()
,或者如果可能,甚至单独使用
update()
。。。并使处理成为自定义管理器或queryset方法。select_related()和prefetch_related()对于优化django查询非常有用。这篇文章可能会有帮助:@Surajano process_post是一个芹菜任务,它将在后台运行,不会更新帖子