2012-07-09 45 views
0

我期待postgres需要一些时间,但并不期望它不会成为瓶颈,我该如何解决这个问题?不断使用此代码在Django中进行深度复制 - 如何避免?

2772856 function calls (2578490 primitive calls) in 32.361 seconds 

Ordered by: internal time 

ncalls tottime percall cumtime percall filename:lineno(function) 
127921/19340 3.670 0.000 11.486 0.001 /usr/lib/python2.7/copy.py:145(deepcopy) 
2240 3.031 0.001 3.244 0.001 {method 'execute' of 'psycopg2._psycopg.cursor' objects} 
114402 1.541 0.000 2.348 0.000 /usr/lib/python2.7/copy.py:267(_keep_alive) 

------------------------------------------- ---------------------------------------

suppliers = models.Supplier.objects.all().order_by('company') 
    for supplier in suppliers : 
     sup = {} 
     sup['company'] = supplier.company 
     sup['supplies'] = get_supplies(1, supplier.uuid) 
     sup['category'] = 'Supplier' 
     if isocode == None : 
      addresses = models.Address.objects.filter(company = supplier.company) 
     else : 
      addresses = models.Address.objects.filter(company = supplier.company, country_iso = isocode) 
     sup['contacts'] = models.Contact.objects.filter(address__in=addresses) 
     company_list.append(sup) 

---- -------------------------------------------------- ----------------------------

def get_supplies (bought_in_controlpanel_id, supplier_uuid) : 

    supplier = None 
    activenode = None 

    if supplier_uuid is not None : 
     supplier = models.Supplier.objects.get(uuid = supplier_uuid) 

    try : 
     activenode = boughtin.BoughtInControlPanel.objects.get (pk = 1) 
    except : 
     pass 

    supplies = boughtin.BoughtInControlPanel.objects.filter (parent = activenode) 
    for supply in supplies : 
     supply.checked = 0 
     supply.disabled = "" 
     supply.open  = 0 

     if supplier_uuid is not None : 
      try : 
       models.Supplies.objects.get(supplier = supplier, bought_in_control_panel = supply) 
       supply.checked = 1 
      except : 
       supply.open = 1 

    return supplies 

回答

3

当您在循环中查询数据库时,性能通常很差。尽量避免这一点。

为什么不继续使用关系和__in查询? =)

我认为这应该以较少的SQL查询工作的第一个例子:

company_list = models.Supplier.objects.values_list('company', flat=True) 

filter_kwargs = dict(address__company__in=company_list) 

if isocode is not None: 
    filter_kwargs.update(dict(address__company__isocode=isocode)) 

sup['contacts'] = models.Contact.objects.filter(**filter_kwargs) 

关于get_supplies(),我会避免在循环Supplies.objects.get(),除非你确定它会正好击中一些时间。在循环之前收集带有一个较大查询的耗材列表可能会更好,然后只需检查所需项目是否存在于该列表中。尽管你应该分析两种变体并选择更快的变体。

+0

isocode提供给函数'def company_list(area,sub_cat,isocode = None):'我修剪了很多函数,因为它不是相关的(这个替代路径转到不同的模型但是做的完全一样东西) – Jharwood 2012-07-09 12:34:01

+0

但基本上我所做的全部都是'return company_list' :) – Jharwood 2012-07-09 12:34:40

+0

更新了一个可能的解决方法来解释'isocode',我没有想到最初。 – Tony 2012-07-09 12:40:59