我有一个函数可以跨多个对象执行大量的数据库查询:
def some_func(user):
group1 = user.manytomanyfield1.all()
allinstances = []
for item in group1:
allinstances += group1.manytomanyfield2.all()
然后我有一个列表' allinstances'这是对象的复合。然后,我需要检查创建的' allinstances' list包含具有属性&name; name'这对于所有实例中的一些对象是相同的。列出并删除重复项:
names = []
doubleList = []
for number, object1 in enumerate(allinstances):
if object1.name not in names:
names.append(object1.name)
else:
doubleList.append(number)
doubleList.reverse()
for item in doubleList:
allinstances.pop(item)
return allinstances
当所有实例的大小很小时,该功能执行得非常快。但我的应用程序范围是这样的,它最常见的工作量可能是数万,可能是数十万个对象1所以'所有实例' list会很大,所以函数执行会花费很长时间。目前有~25000'对象1' allinstances'函数执行需要10秒。这对我来说是负担不起的,因为返回的列表进一步被放入Paginator中,并且具有object1的详细信息的Listview是根据结果构造的,因此用户必须在函数执行时等待。
我看到以下选项可以减少这个瓶颈: 1.优化功能执行速度 2.更改我的视图以使用AJAX并将函数执行重新路由到异步任务队列,如Celery。然后页面上的AJAX会在某些时间间隔内查询结果,当任务完成时,会在页面上添加结果。
在这种情况下是否有最佳做法? 也许还有其他更可行的解决方案? 欢迎任何代码改进建议。
答案 0 :(得分:1)
一个非常快速的优化是使names
成为一个集合,因为列表查找是线性的(O(n))而set set是常量的(O(1)):
names = set()
doubleList = []
for number, object1 in enumerate(allinstances):
if object1.name not in names:
names.add(object1.name)
答案 1 :(得分:0)
我认为你的很多性能问题来自Django,当你有大量记录时,必须运行~25000个查询。
prefetch_related就是我在这里使用的。
代码的第一部分如下所示:
def some_func(user):
group1 = user.manytomanyfield1.all().prefetch_related('manytomanyfield2')
allinstances = []
for item in group1:
allinstances += item.manytomanyfield2.all()