diff mbox series

[v2,1/2] api: EventList: change select_related() to prefetch_related()

Message ID 20180321111033.15385-1-dja@axtens.net
State Accepted
Headers show
Series [v2,1/2] api: EventList: change select_related() to prefetch_related() | expand

Commit Message

Daniel Axtens March 21, 2018, 11:10 a.m. UTC
select_related() creates a single giant query that JOINs the required
tables together in the DB. prefetch_related() does a similar thing,
but at the Django layer - for all referenced models, it makes a
separate query to the DB to fetch them.

This massively, massively simplifies the job the DB has to do:
instead of creating a massive, sparse results table with many
columns, we do 1 query for the events, and then query for only
patches/cover letters/series/projects etc referenced in those 30
events.

Tested with cURL + JSON renderer + Postgres w/ ~100k patches,
request time went from 1.5s to 0.25s, a 6x speedup.

Tested with cURL + JSON renderer + MySQL w/ ~33k patches,
request time went from ~2.2s to ~0.20s, an ~11x speedup.

Signed-off-by: Daniel Axtens <dja@axtens.net>
---
 patchwork/api/event.py | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

Comments

Daniel Axtens April 5, 2018, 9:37 a.m. UTC | #1
These are conceptually compatible with Stephen's ongoing refactoring,
whether or not we go ahead with that in the end, this at least doesn't
close it off. Applied.

Regards,
Daniel

Daniel Axtens <dja@axtens.net> writes:

> select_related() creates a single giant query that JOINs the required
> tables together in the DB. prefetch_related() does a similar thing,
> but at the Django layer - for all referenced models, it makes a
> separate query to the DB to fetch them.
>
> This massively, massively simplifies the job the DB has to do:
> instead of creating a massive, sparse results table with many
> columns, we do 1 query for the events, and then query for only
> patches/cover letters/series/projects etc referenced in those 30
> events.
>
> Tested with cURL + JSON renderer + Postgres w/ ~100k patches,
> request time went from 1.5s to 0.25s, a 6x speedup.
>
> Tested with cURL + JSON renderer + MySQL w/ ~33k patches,
> request time went from ~2.2s to ~0.20s, an ~11x speedup.
>
> Signed-off-by: Daniel Axtens <dja@axtens.net>
> ---
>  patchwork/api/event.py | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/patchwork/api/event.py b/patchwork/api/event.py
> index 0d97af227f0e..7e04b716af1a 100644
> --- a/patchwork/api/event.py
> +++ b/patchwork/api/event.py
> @@ -96,7 +96,7 @@ class EventList(ListAPIView):
>  
>      def get_queryset(self):
>          return Event.objects.all()\
> -            .select_related('project', 'patch', 'series', 'cover',
> -                            'previous_state', 'current_state',
> -                            'previous_delegate', 'current_delegate',
> -                            'created_check')
> +            .prefetch_related('project', 'patch', 'series', 'cover',
> +                              'previous_state', 'current_state',
> +                              'previous_delegate', 'current_delegate',
> +                              'created_check')
> -- 
> 2.14.1
diff mbox series

Patch

diff --git a/patchwork/api/event.py b/patchwork/api/event.py
index 0d97af227f0e..7e04b716af1a 100644
--- a/patchwork/api/event.py
+++ b/patchwork/api/event.py
@@ -96,7 +96,7 @@  class EventList(ListAPIView):
 
     def get_queryset(self):
         return Event.objects.all()\
-            .select_related('project', 'patch', 'series', 'cover',
-                            'previous_state', 'current_state',
-                            'previous_delegate', 'current_delegate',
-                            'created_check')
+            .prefetch_related('project', 'patch', 'series', 'cover',
+                              'previous_state', 'current_state',
+                              'previous_delegate', 'current_delegate',
+                              'created_check')