我有一个在Django中运行的函数。应该根据用户位置来计算位置的距离。它起作用了,唯一的问题是我感觉我当前的实现可能缺乏性能。这往往会花费很多时间。这是代码:
def resolve_near_by_branches(self, info, **kwargs):
ul_raw = kwargs.get('user_location')
ul_l = ul_raw.split(',')
user_location = (float(ul_l[0]), float(ul_l[1]))
final_b = []
if kwargs.get('category') is None:
es = Establishment.objects.distinct().all()
else:
es = Establishment.objects.distinct().filter(
category__code_name__exact=kwargs.get('category'),
)
for e in es:
for branch in e.branches.all():
b_l = (float(branch.location.latitude.replace(' ', "")), float(branch.location.longitude.replace(' ', "")))
# if geodesic(user_location, b_l).km < 9000000:
final_b.append((geodesic(user_location, b_l).m, branch))
final_data = sorted(final_b, key=lambda x: x[0])
print(final_data)
# print([i[1] for i in final_b])
return [i[1] for i in final_data]
如果您对我可以如何加快速度有任何建议,请贡献力量。
答案 0 :(得分:2)
一个明显的改进是使用prefetch_related()
,这是因为您在每次迭代中访问的都是逆向关系。这告诉Django在评估时再执行一次额外的数据库查询,以检索反向关系,而不是每次访问时都进行一次,从而减少了查询。
def resolve_near_by_branches(self, info, **kwargs):
ul_raw = kwargs.get('user_location')
ul_l = ul_raw.split(',')
user_location = (float(ul_l[0]), float(ul_l[1]))
final_b = []
if kwargs.get('category') is None:
es = Establishment.objects.distinct().all()
else:
es = Establishment.objects.distinct().filter(
category__code_name__exact=kwargs.get('category'),
)
for e in es.prefetch_related('branches'):
for branch in e.branches.all():
b_l = (float(branch.location.latitude.replace(' ', "")), float(branch.location.longitude.replace(' ', "")))
# if geodesic(user_location, b_l).km < 9000000:
final_b.append((geodesic(user_location, b_l).m, branch))
final_data = sorted(final_b, key=lambda x: x[0])
print(final_data)
# print([i[1] for i in final_b])
return [i[1] for i in final_data]
我最近做了一个Django ORM optimization cheat sheet,希望在寻求快速优化时会有所帮助。