From 75917a9019b3a682534e8056cdff6c72bf45fe32 Mon Sep 17 00:00:00 2001 From: Evy Kassirer Date: Fri, 5 Sep 2025 11:18:18 -0700 Subject: [PATCH] subscription_info: Improve subscriber fetch preformance. Discussed here: https://chat.zulip.org/#narrow/channel/141-kandra-ops/topic/partial.20subscribers.20query.20does.20users.20sequential.20scan/near/2255421 (cherry picked from commit 31505e90f7715ae1e2d9c11db54fb488339a564c) --- zerver/lib/subscription_info.py | 66 ++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/zerver/lib/subscription_info.py b/zerver/lib/subscription_info.py index 9f3a329518..ae054b68bf 100644 --- a/zerver/lib/subscription_info.py +++ b/zerver/lib/subscription_info.py @@ -603,32 +603,54 @@ def bulk_get_subscriber_user_ids( 20k+ total subscribers. (For large realms with lots of default streams, this function deals with LOTS of data, so it is important to optimize.) + + One optimization is to use two branches for creating this query, + to avoid joining on zerver_userprofile when we're not sending + partial users. """ - query = SQL( - """ - SELECT - zerver_subscription.recipient_id, - zerver_subscription.user_profile_id - FROM - zerver_subscription - JOIN zerver_userprofile on zerver_userprofile.id = zerver_subscription.user_profile_id - WHERE - zerver_subscription.active AND - zerver_subscription.is_user_active AND - ( - zerver_subscription.recipient_id = ANY (%(full_fetch_recipient_ids)s) - OR + if partial_fetch_recipient_ids: + query = SQL( + """ + SELECT + zerver_subscription.recipient_id, + zerver_subscription.user_profile_id + FROM + zerver_subscription + JOIN zerver_userprofile on zerver_userprofile.id = zerver_subscription.user_profile_id + WHERE + zerver_subscription.active AND + zerver_subscription.is_user_active AND ( - zerver_subscription.recipient_id = ANY (%(partial_fetch_recipient_ids)s) AND - (zerver_userprofile.is_bot OR (NOT zerver_userprofile.long_term_idle)) + zerver_subscription.recipient_id = ANY (%(full_fetch_recipient_ids)s) + OR + ( + zerver_subscription.recipient_id = ANY (%(partial_fetch_recipient_ids)s) AND + (zerver_userprofile.is_bot OR (NOT zerver_userprofile.long_term_idle)) + ) ) - ) - ORDER BY - zerver_subscription.recipient_id, - zerver_subscription.user_profile_id - """ - ) + ORDER BY + zerver_subscription.recipient_id, + zerver_subscription.user_profile_id + """ + ) + else: + query = SQL( + """ + SELECT + zerver_subscription.recipient_id, + zerver_subscription.user_profile_id + FROM + zerver_subscription + WHERE + zerver_subscription.active AND + zerver_subscription.is_user_active AND + zerver_subscription.recipient_id = ANY (%(full_fetch_recipient_ids)s) + ORDER BY + zerver_subscription.recipient_id, + zerver_subscription.user_profile_id + """ + ) cursor = connection.cursor() cursor.execute(