我正在迭代一个包含500-1000个对象的django查询集。相应的模型/表格中也有7个字段。问题是,在考虑需要在我的应用程序中完成的所有其他数据处理时,迭代过程需要大约3秒钟。
编辑: 这是我的模特:
class Node(models.Model):
node_id = models.CharField(null=True, blank=True, max_length=30)
jobs = models.TextField(null=True, blank=True)
available_mem = models.CharField(null=True, blank=True, max_length=30)
assigned_mem = models.CharField(null=True, blank=True ,max_length=30)
available_ncpus = models.PositiveIntegerField(null=True, blank=True)
assigned_ncpus = models.PositiveIntegerField(null=True, blank=True)
cluster = models.CharField(null=True, blank=True, max_length=30)
datetime = models.DateTimeField(auto_now_add=False)
这是我的初始查询,速度非常快:
timestamp = models.Node.objects.order_by('-pk').filter(cluster=cluster)[0]
self.nodes = models.Node.objects.filter(datetime=timestamp.datetime)
然后,我去迭代,需要3秒,我尝试了两种方法,如下所示:
def jobs_by_node(self):
"""returns a dictionary containing keys that
are strings of node ids and values that
are lists of the jobs running on that node."""
jobs_by_node = {}
#iterate over nodes and populate jobs_by_node dictionary
tstart = time.time()
for node in self.nodes:
pass #I have omitted the code because the slowdown is simply iteration
tend = time.time()
tfinal = tend-tstart
return jobs_by_node
其他方法:
all_nodes = self.nodes.values('node_id')
tstart = time.time()
for node in all_nodes:
pass
tend = time.time()
tfinal = tend-tstart
我通过引用this帖子尝试了第二种方法,但它仍然没有加快我的迭代速度。我在网上搜索无济于事。任何优化此过程的帮助将不胜感激。谢谢。
注意:我正在使用Django 1.5和Python 2.7.3
答案 0 :(得分:1)
检查已发出的SQL查询。您可以使用print
声明:
print self.nodes.query # in general: print queryset.query
那应该给你一些:
SELECT id, jobs, ... FROM app_node
然后运行EXPLAIN SELECT id, jobs, ... FROM app_node
,你就会知道到底出了什么问题。
假设您在运行EXPLAIN后知道问题是什么,并且添加索引这样的简单解决方案是不够的,您可以考虑例如每隔X分钟(在cron作业或Celery任务中)将相关行提取到单独的表,并在应用程序中使用该单独的表。
如果您正在使用PostgreSQL,您还可以使用materialized views并将其“换行”在unmanaged Django model中。