我与Django一起工作,拥有大约30.000张记录的大型数据库。我的工作是对所有的记录做一些简单的计算。数据库中的数据涉及50人。我必须过滤每个人的行,然后计算10列中每个列的平均值。因此,我需要过滤数据50次(因为我必须分别计算和显示50个人的数据),并做数学计算。我只使用了一行代码(循环超过50次)就完成了这个任务:
qs = Mymodel.objects.filter(person=person).values()
records[i] = qs.aggregate(Avg('question-1'),Avg('question-2'),...Avg('question-10'))
# Heavy SQL operation但是django调试工具栏说这个请求大约需要6.6秒才能完成(大约有55个sql查询,这是我所期望的)。
这只是一项任务,我需要做额外的7-8个类似的数学任务,所以整个工作可以轻松地总结到400-500个sql查询。
我关心性能问题,所以我想知道什么是更好、更快的方法--是应该直接在数据库中使用行筛选和聚合查询来计算,还是应该预取包含30.000行的整个数据库表(但预计将来每年将增加30.000行),并在python中进行计算呢?
发布于 2016-07-16 20:31:05
我对django一无所知,但我确实了解SQL。我有一个解决方案的大纲给你。
30,000张唱片不算大,这可不是热身。您的代码之所以慢,是因为您要向每个人发出一个查询。使用SQL的GROUP特性,DBMS可以更快地为所有人生成多个聚合:
select person, avg(question-1), avg(question-2)
from tablename
group by person重要的规则是,select集中的每个非聚合都必须出现在group by集中。
如果您的所有聚合都是关于person的,并且都来自同一个表,那么只需要一个查询。我敢打赌,处理结果要比DBMS需要花费更长的时间。
发布于 2016-07-16 20:31:16
注解可以帮助并将SQL查询减少到一个:
Person.objects.annotate(
Avg('question-1'), Avg('question-2'), ..., Avg('question-10')
)https://stackoverflow.com/questions/38414050
复制相似问题