2012-07-09 47 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