首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django循环.save()时间问题

Django循环.save()时间问题
EN

Stack Overflow用户
提问于 2017-01-25 14:35:01
回答 3查看 778关注 0票数 1

我有下面的代码,所有的事情都按它的要求进行,每个循环的运行时间都会不同。我已经将其缩小到.save()函数,因为每次迭代平均运行.008秒。.save()从.008秒到1.13秒不等。

当执行113次迭代时,1.13秒开始加起来。

有什么加快速度的建议吗?表的大小可达45,000行数据。

代码语言:javascript
复制
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)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-01-25 14:59:35

更新而不是获取和保存

您正在获取一个对象,然后更新它的字段并将其保存回来。这是两个命中的分贝。你可以在一次手术中完成。使用更新

代码语言:javascript
复制
FloorTracker.objects.filter(showroom_number=strNum,mattress=bed).update(
     lastupdate = str(timezone.now(),suggested_retail = sretail ....)

这比检索和保存更快,而且更安全!这是一个原子操作,在进行编辑时,使用检索、编辑保存您将面临另一个线程更新数据库的风险,而该数据将被破坏。

使用超越

正如在另一个答案中所建议的那样,将整个事情封装在一个事务中,并在结束时提交。这样会快得多

用户数据库默认值

不要在代码中为无实例和未找到实例分配值,而是使用默认值。这将节省一些操作,并导致一些速度。

避免重复获取相同的对象

您有多个这样的电话:

代码语言:javascript
复制
request.POST.get('ub_' + bed) 

您可以这样做一次,并重用该值。

代码语言:javascript
复制
ub_bed = request.POST.get('ub_' + bed) 

这里的储蓄是很小的。

把request.POST当作字典

如果您确信所有字段都已填充(如果您在这里使用django表单而不是依赖原始post数据,您真的可以这样做),您可以访问request.POST项,如

请求‘’cb_‘+床

但是性能的改善将是微不足道的。

索引

最后但并非最不重要的是,在showroom_number, mattress上创建一个索引--这可能会带来很大的提升。

票数 3
EN

Stack Overflow用户

发布于 2017-01-25 14:55:30

Django的默认情况是在自动提交模式下运行,所以如果您还没有这样做(我想您已经提到了),将所有更新包装在一个事务中肯定会提高性能。

票数 1
EN

Stack Overflow用户

发布于 2017-01-25 16:08:35

按照e4c5的一些建议,我已经做了一些改进,但每次迭代都有可变的时间。大多数迭代现在需要.005秒,但其中大约四分之一仍然需要1.3秒(非常可靠的1.31或1.32秒)。

时间问题是一个问题,因为我从服务器主机上得到超时,而这对我的用户来说是失败的。我真的需要它在20秒内可靠。从30秒到90秒。

这是我对代码所做的更新。即使在阅读完transaction.atomic之后,我也不确定我是否完全理解了它,但我认为这是正确的:

代码语言:javascript
复制
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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41854247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档