我正在優化我們的(第一個)Django項目中的緩慢頁面加載。整個項目不會測試狀態管理,所以有些協議會有計劃執行的情況。目前的代碼是:Django:我如何避免不必要的SQL語句?
protocols = Protocol.active.filter(team=team, release=release)
cases = Case.active.filter(protocol__in=protocols)
caseCount = cases.count()
plannedExecs = Planned_Exec.active.filter(case__in=cases, team=team, release=release)
# Start aggregating test suite information
# pgi Model
testSuite['pgi_model'] = []
for pgi in PLM.objects.filter(release=release).values('pgi_model').distinct():
plmForPgi = PLM.objects.filter(pgi_model=pgi['pgi_model'])
peresults = plannedExecs.filter(plm__in=plmForPgi).count()
if peresults > 0:
try:
testSuite['pgi_model'].append((pgi['pgi_model'], "", "", peresults, int(peresults/float(testlistCount)*100)))
except ZeroDivisionError:
testSuite['pgi_model'].append((pgi['pgi_model'], "", "", peresults, 0))
# Browser
testSuite['browser'] = []
for browser in BROWSER_OPTIONS:
peresults = plannedExecs.filter(browser=browser[0]).count()
try:
testSuite['browser'].append((browser[1], "", "", peresults, int(peresults/float(testlistCount)*100)))
except ZeroDivisionError:
testSuite['browser'].append((browser[1], "", "", peresults, 0))
# ... more different categories are aggregated below, then the report is generated...
該代碼製作了大量的SQL語句。 PLM.objects.filter(release=release).values('pgi_model').distinct()
返回一個包含50個字符串的列表,並且這兩個過濾器操作都爲每個字符串執行一條SQL語句,這意味着100個SQL語句僅用於此循環。 (另外,它似乎應該使用values_list
與flat=True
。)
由於我想獲取有關相關案件和計劃執行信息,我想我只需要檢索這兩個表,然後對此進行一些分析。使用filter和count()似乎是當時顯而易見的解決方案,但我想知道如果使用.values()構建相關案例和計劃執行信息的代碼,然後再分析它,那麼是不是更好?以避免不必要的SQL語句。任何有用的建議?謝謝!
編輯:在試圖分析這個以瞭解時間在哪裏,我使用Django Debug工具欄。它解釋說,有超過200個查詢,並且每個查詢都運行得非常快,所以總的來說它們佔用的時間很少。但是,SQL的執行速度是否相對較快,但是ORM的構建會增加,因爲它發生了200次以上?我重構了一個需要花費3分鐘才能加載的上一頁,並使用values()而不是ORM,從而將頁面加載到2.7秒和5條SQL語句。
你或許應該配置文件,看是否放緩是由於SQL,或到Python代碼。 – Oliver 2012-03-14 15:25:17
剛剛編輯我的答案 - 我使用Django Debug工具欄進行分析,這意味着SQL調用都發生得相對較快,但很難看出時間在哪裏。您使用哪些工具進行分析? – Nathan 2012-03-14 15:40:24
您使用的數據庫是? – 2012-03-14 17:30:13