2012-09-08 34 views
1

我的代碼中有性能問題。我對Python有點新,我想不出有更好的方法去做下面的代碼。我的代碼性能不佳

我有一個名爲「cdr」的表不是django項目的一部分的外部數據庫,我需要對這些行進行一些計算。爲了得到我的變量的值,我正在查詢我的cdr表中的每一行,這使我的代碼非常慢。

這是我在view.py

def cdr_adm(request): 
     cursor = connections['cdr'].cursor() 
     cursor.execute("SELECT calldate, dst, billsec, accountcode, disposition, userfield FROM cdr where calldate >= '%s' and calldate < '%s' and disposition like '%s' and accountcode like '%s' and dst like '%s' and userfield like '%s'" %(start_date, end_date, status, customer, destino, provider)) 
     result = cursor.fetchall() 
     time = 0 
     price = 0 
     price_prov = 0 
     count = 0 
     time_now = 0 
     ANS = 0 
     asr = 0 
     rate_cust = 0 
     rate_prov = 0 

     for call in result: 
       if call[3]: 
         #These 2 lines are the problem - It's very slow to run for all rows. 
         rate_cust = User.objects.get(username = call[3]) 
         rate_prov = Provider.objects.get(name = call[5]) 
         time_now = call[2]/60 
         time = time + time_now 
         count = count + 1 
         price = price + (float(rate_cust.first_name) * time_now) 
         price_prov = price_prov + (float(rate_prov.rate) * time_now) 
         if call[4] == "ANSWERED": 
           ANS = ANS + 1 
     time = float(time) 
     lucro = price - price_prov 
     lucro = float(lucro) 
     if count > 0: 
       asr = (ANS/count) * 100 
     return render_to_response("cdr_all.html", 
       {'calls':result,'price':price,'time':time,'count':count,'customers':customers, 'providers':providers,'price_prov':price_prov, 'lucro':lucro, 'asr':asr }, context_instance=RequestContext(request)) 

我在想創造它的字典和搜索類,但我不知道這件事了。

+3

我對Django不太瞭解,但是它不是爲你抽象數據庫操作嗎?爲什麼您必須手動構建SQL查詢,並有可能未經過類型化的輸入? – Blender

+1

請縮小代碼的大小。你不可能需要所有的邏輯來演示性能問題。 –

+1

@Blender:他提到cdr是一個外部數據庫,而不是由Django的模型創建的。 (在其他時候,他正確使用Django的模型,比如'User.objects.get(username = call [3])') –

回答

2

您可以創建所有UserProvider對象,由什麼你感興趣的,像這樣的索引的字典:

users = dict([(u.username, u) for u in User.objects.all()]) 
providers = dict([(p.name, p) for p in Provider.objects.all()]) 

(請確保您的循環做到這一點for call in result:外!)你可以然後改變你的慢查詢到:

    rate_cust = users[call[3]] 
        rate_prov = provided[call[5]] 

我猜有相當少的用戶和供應商不是調用,這意味着他們留在字典中會快於訪問不是使EA的一個查詢通話。

+0

謝謝大衛,它幫助了很多。完美工作。時間減少90%。 –