我正在优化我们的(第一个)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