From 56243f6529100dd7c2cd3a23f7c7b4581f0e1c93 Mon Sep 17 00:00:00 2001 From: Wesley Aptekar-Cassels Date: Thu, 9 Mar 2023 00:34:45 -0500 Subject: [PATCH] Optimize HomeStream.get_audience This splits HomeStream.get_audience into two separate database queries, in order to more effectively take advantage of the indexes we have. Combining the user ID query and the user following query means that Postgres isn't able to use the index we have on the userfollows table. The query planner claims that the userfollows query should be about 20 times faster than it was previously, and the id query should take a negligible amount of time, since it's selecting a single item by primary key. We don't need to worry about duplicates, since there is a constraint preventing a user from following themself. Fixes: #2720 --- bookwyrm/activitystreams.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/bookwyrm/activitystreams.py b/bookwyrm/activitystreams.py index ea629a318..2f9e98042 100644 --- a/bookwyrm/activitystreams.py +++ b/bookwyrm/activitystreams.py @@ -160,14 +160,15 @@ class HomeStream(ActivityStream): key = "home" - def _get_audience(self, status): + def get_audience(self, status): audience = super()._get_audience(status) if not audience: return [] - return audience.filter( - Q(id=status.user.id) # if the user is the post's author - | Q(following=status.user) # if the user is following the author - ).distinct() + # if the user is the post's author + ids_self = [user.id for user in audience.filter(Q(id=status.user.id))] + # if the user is following the author + ids_following = [user.id for user in audience.filter(Q(following=status.user))] + return ids_self + ids_following def get_statuses_for_user(self, user): return models.Status.privacy_filter(