我有以下代码,一切都按预期进行,每个循环的运行时间可能会有所不同。我已将其缩小到.save()
函数,因为查询平均每次迭代运行时间为.008秒。 .save()
需要从.008秒到1.13秒。
执行113次迭代时,1.13秒开始累加。
有什么建议可以加快速度吗? 表格大小最多为45,000行数据。
for mega, company, family, bed, sretail in beds:
matt = FloorTracker.objects.get(showroom_number=strNum,mattress=bed)
matt.brand = company
matt.family = family
matt.company = mega
matt.suggested_retail = sretail
matt.on_floor = 0 if request.POST.get('cb_' + bed) == None else 1
matt.in_comparison = 0 if request.POST.get('cb_' + bed + '_comparison') == None else 1
matt.in_vzone = 0 if request.POST.get('cb_' + bed + '_vzone') == None else 1
matt.size = "" if request.POST.get('sz_' + bed) == 'blank' or not request.POST.get('sz_' + bed) else request.POST.get('sz_' + bed)
matt.underbed = "" if request.POST.get('ub_' + bed) == 'blank' or not request.POST.get('ub_' + bed) else request.POST.get('ub_' + bed)
matt.lastupdate = str(timezone.now())
t0 = time.time()
matt.save()
t1 = time.time()
total = t1-t0
print('query 1:', matt.mattress, total)
答案 0 :(得分:3)
您正在获取一个对象,然后更新它的字段并将其保存回来。这是db上的两次点击。你可以在一次操作中完成。使用update
FloorTracker.objects.filter(showroom_number=strNum,mattress=bed).update(
lastupdate = str(timezone.now(),suggested_retail = sretail ....)
这比检索和保存更快,而且更安全!这是一个原子操作,使用检索,编辑可以避免在进行编辑时另一个线程更新数据库的风险,并且数据将被破坏。
正如在其他答案中所建议的那样,将整个事物包装在事务中并在最后提交。这会快得多
不是在代码中为None和未找到的实例分配值,而是使用默认值。这将节省一些操作并导致一些速度。
request.POST.get('ub_' + bed)
您可以执行一次并重复使用值
ub_bed = request.POST.get('ub_' + bed)
此处保存的规模很小。
如果您确信所有字段都已填充(如果您在此处使用django表单而不是依赖原始发布数据,则可能真的如此)您可以访问request.POST项目
request.POST [' CB _' +床]
但性能改善将是微不足道的
最后但并非最不重要的是,在showroom_number, mattress
上创建一个索引,这可能会带来很大的推动。
答案 1 :(得分:1)
Django的默认设置是在自动提交模式下运行,所以如果你还没有这样做(我假设你会提到它),precedence肯定会提高性能。
答案 2 :(得分:0)
最简单的加速是避免在每次循环迭代时进行一次查询。
bed_list = [b[3] for b in beds] track_qs = FloorTracker.objects.filter(showroom_number=strNum, mattress__in=bed_list) trackers = {t.mattress: t for t in track_qs} for mega, company, family, bed, sretail in beds: matt = trackers[bed] ...
另一种方法是累积所需的更新并立即执行所有更新,而不是进行大量单项更新。
答案 3 :(得分:0)
根据e4c5的一些建议,我已经有了一些改进,但每次迭代仍然有不同的时间。大多数迭代现在需要.005秒,但其中大约四分之一仍需要1.3秒(相当可靠的1.31或1.32秒)。
时机问题是因为我从服务器主机获得超时,这对我的用户来说是失败的。我真的需要它在20秒内可靠。我们的出现时间从30秒到90秒不等。
以下是我对代码所做的更新。我不确定我是否完全理解transaction.atomic即使在阅读之后我也认为这是正确的:
def saveData(request,strNum, brand):
#List of beds to loop through
import time
from django.db import transaction
beds = bedSelect(brand)
t3 = time.time()
store = storeList.objects.get(storenumber=strNum)
with transaction.atomic():
for mega, company, family, bed, sretail in beds:
try:
t0 = time.time()
FloorTracker.objects.filter(showroom_number=strNum,mattress=bed).update(
user = store.user,
showroom_number = store,
brand = company,
family = family,
mattress = bed,
company = mega,
suggested_retail = sretail,
on_floor = 0 if request.POST.get('cb_' + bed) == None else 1,
in_comparison = 0 if request.POST.get('cb_' + bed + '_comparison') == None else 1,
in_vzone = 0 if request.POST.get('cb_' + bed + '_vzone') == None else 1,
size = "" if request.POST.get('sz_' + bed) == 'blank' or not request.POST.get('sz_' + bed) else request.POST.get('sz_' + bed),
underbed = "" if request.POST.get('ub_' + bed) == 'blank' or not request.POST.get('ub_' + bed) else request.POST.get('ub_' + bed),
lastupdate = str(timezone.now()))
t1 = time.time()
total = t1-t0
print(total)