Skip to content

Commit 90d1cf8

Browse files
authored
Dashboard: optimize projects queryset (#12383)
This used to be 35 queries. I found another optimization to make it to constant time, but will open another PR as it may produce a slow query..
1 parent 9928bf4 commit 90d1cf8

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

readthedocs/projects/querysets.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,11 @@ def prefetch_latest_build(self):
144144

145145
# Prefetch the latest build for each project.
146146
subquery = Subquery(
147-
Build.internal.filter(project=OuterRef("project_id"))
148-
.order_by("-date")
149-
.values_list("id", flat=True)[:1]
147+
Build.internal.filter(project=OuterRef("project_id")).order_by("-date").values("pk")[:1]
150148
)
151149
latest_build = Prefetch(
152150
"builds",
153-
Build.internal.filter(pk__in=subquery),
151+
Build.objects.filter(pk__in=subquery).select_related("version"),
154152
to_attr=self.model.LATEST_BUILD_CACHE,
155153
)
156154
return self.prefetch_related(latest_build)

readthedocs/rtd_tests/tests/test_project_views.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
from unittest import mock
22

3-
import pytest
43
from allauth.socialaccount.models import SocialAccount
5-
from django.conf import settings
64
from django.contrib.auth.models import User
75
from django.http.response import HttpResponseRedirect
86
from django.test import TestCase, override_settings
@@ -380,6 +378,30 @@ def setUp(self):
380378
self.client.login(username="eric", password="test")
381379
self.project = get(Project, slug="pip", users=[self.user])
382380

381+
def test_dashboard_number_of_queries(self):
382+
for i in range(10):
383+
project = get(
384+
Project,
385+
slug=f"project-{i}",
386+
users=[self.user],
387+
)
388+
version = project.versions.first()
389+
version.active = True
390+
version.built = True
391+
version.save()
392+
for _ in range(3):
393+
get(
394+
Build,
395+
project=project,
396+
version=version,
397+
success=True,
398+
state=BUILD_STATE_FINISHED,
399+
)
400+
401+
with self.assertNumQueries(24):
402+
r = self.client.get(reverse(("projects_dashboard")))
403+
assert r.status_code == 200
404+
383405
def test_versions_page(self):
384406
self.project.versions.create(verbose_name="1.0")
385407

0 commit comments

Comments
 (0)