【发布时间】:2012-03-14 15:20:36
【问题描述】:
我正在优化我们(第一个)Django 项目中的缓慢页面加载。整个项目进行测试状态管理,因此有些协议具有已计划执行的案例。目前的代码是:
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 语句,这意味着仅这个 for 循环就有 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 代码。
-
刚刚编辑了我的答案 - 我正在使用 Django Debug 工具栏进行分析,这意味着 SQL 调用都发生得相对较快,但在这种情况下很难看出时间在哪里。您使用什么工具进行分析?