Я оптимизирую медленную загрузку страницы в нашем (первом) проекте 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-оператор для каждой строки, что означает 100 SQL-операторов только для цикла for. (Кроме того, похоже, что следует использовать values_list
с flat=True
.)
Поскольку я хочу получить информацию о соответствующих делах и планируемых исполнениях, я думаю, что мне действительно нужно только извлечь эти две таблицы, а затем провести некоторый анализ по этому вопросу. Использование filter и count () в то время казалось очевидным решением, но мне интересно, не лучше ли мне было бы просто составить изложение соответствующего случая и информации планируемого выполнения с использованием .values (), а затем проанализировать это, поэтому как избежать ненужных операторов SQL. Любой полезный совет? Спасибо!
Редактировать: В попытке профилировать это, чтобы понять, куда идет время, я использую панель инструментов Django Debug. Это объясняет, что существует более 200 запросов, каждый из которых выполняется очень быстро, поэтому в целом они занимают очень мало времени. Однако может ли быть так, что выполнение SQL выполняется относительно быстро, но сборка ORM складывается, учитывая, что это происходит более 200 раз? Я произвел рефакторинг предыдущей страницы, загрузка которой заняла 3 минуты, и использовал values () вместо ORM, таким образом снизив загрузку страницы до 2,7 секунды и 5 операторов SQL.