Patch list is pretty slow partially because it filters on a query
with a lot of extra fields. For example, I suspect that the tag count
fields are computed even for rows that did not make it into the final
result, same with joins.
This patch changes this by separating the filtering stage, in which only
patch IDs are queried, and the aggregation stage.

Signed-off-by: Franciszek Stachura <[email protected]>
---
Unfortunately, the ID query cannot be a subquery, as MySQL does not
support LIMIT/OFFSET in subqueries.
---
 .../patchwork/partials/patch-list.html        |  2 +-
 patchwork/views/__init__.py                   | 23 +++++++++++++++----
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/patchwork/templates/patchwork/partials/patch-list.html 
b/patchwork/templates/patchwork/partials/patch-list.html
index 981ceee5..b9bb62d2 100644
--- a/patchwork/templates/patchwork/partials/patch-list.html
+++ b/patchwork/templates/patchwork/partials/patch-list.html
@@ -154,7 +154,7 @@
     </thead>
 
     <tbody>
-{% for patch in page.object_list %}
+{% for patch in patches %}
       <tr id="patch-row:{{patch.id}}" data-patch-id="{{patch.id}}">
 {% if user.is_authenticated %}
         <td id="select-patch:{{patch.id}}" style="text-align: center;">
diff --git a/patchwork/views/__init__.py b/patchwork/views/__init__.py
index 92adbbcc..e8621301 100644
--- a/patchwork/views/__init__.py
+++ b/patchwork/views/__init__.py
@@ -280,13 +280,26 @@ def generic_list(
         else:
             context['filters'].set_status(filterclass, setting)
 
+    # Filtering
+
     if patches is None:
         patches = Patch.objects.filter(project=project)
 
-    # annotate with tag counts
-    patches = patches.with_tag_counts(project)
+    patch_ids = patches
+
+    patch_ids = patch_ids.only('id')
+    patch_ids = context['filters'].apply(patch_ids)
+    if not editable_order:
+        patch_ids = order.apply(patch_ids)
 
-    patches = context['filters'].apply(patches)
+    paginator = Paginator(request, patch_ids)
+    patch_ids = list(
+        paginator.current_page.object_list.values_list('id', flat=True)
+    )
+
+    # Aggregation
+
+    patches = patches.filter(id__in=patch_ids)
     if not editable_order:
         patches = order.apply(patches)
 
@@ -321,11 +334,13 @@ def generic_list(
         )
     )
 
-    paginator = Paginator(request, patches)
+    # annotate with tag counts
+    patches = patches.with_tag_counts(project)
 
     context.update(
         {
             'page': paginator.current_page,
+            'patches': patches,
             'patch_form': properties_form,
             'create_bundle_form': create_bundle_form,
             'project': project,
-- 
2.55.0

_______________________________________________
Patchwork mailing list
[email protected]
https://lists.ozlabs.org/listinfo/patchwork

Reply via email to