Skip to content

Commit

Permalink
Query optimization for the Briefcase viewset (#2142)
Browse files Browse the repository at this point in the history
* Calculate instance_count only when the `instances` queryset is a slice

Avoid multiple calls to `.count()` which case the application to
re-query the database

* Retrieve the `pk` & `uuid` fields only

Minor optimization for the `SELECT` query as we do not utilize any of
the other columns within the instance table in the BriefcaseViewSet

* Retrieve instance_count by retrieving the length of the `instances` queryset

Not using the `num_of_submissions` attribute since it counts submissions
which have not yet received all media files yet.

* Update comment

* Remove trailing whitespace

* Check if `instance_count` is greater than 0
  • Loading branch information
DavisRayM committed Oct 6, 2021
1 parent c5030cb commit ee9c156
Showing 1 changed file with 13 additions and 6 deletions.
19 changes: 13 additions & 6 deletions onadata/apps/api/viewsets/briefcase_viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,9 @@ def filter_queryset(self, queryset):
xform_kwargs['user__username__iexact'] = username
xform = get_form(xform_kwargs)
self.check_object_permissions(self.request, xform)
instances = Instance.objects.filter(xform=xform,
deleted_at__isnull=True)
instances = Instance.objects.filter(
xform=xform, deleted_at__isnull=True).values(
'pk', 'uuid')
if xform.encrypted:
instances = instances.filter(media_all_received=True)
instances = instances.order_by('pk')
Expand All @@ -143,10 +144,16 @@ def filter_queryset(self, queryset):
if num_entries:
instances = instances[:num_entries]

if instances.count():
last_instance = instances[instances.count() - 1]
self.resumptionCursor = last_instance.pk
elif instances.count() == 0 and cursor:
# Using len() instead of .count() to prevent an extra
# database call; len() will load the instances in memory allowing
# us to pre-load the queryset before generating the response
# and removes the need to perform a count on the database.
instance_count = len(instances)

if instance_count > 0:
last_instance = instances[instance_count - 1]
self.resumptionCursor = last_instance.get('pk')
elif instance_count == 0 and cursor:
self.resumptionCursor = cursor
else:
self.resumptionCursor = 0
Expand Down

0 comments on commit ee9c156

Please sign in to comment.